---
title: Initialize the JavaScript (Node) SDK prior to v6
slug: feature-experimentation/docs/initialize-sdk-javascript-node-prior-to-v6
docTags: 
createdAt: 2026-08-05T20:39:54.000Z
---

Use the `createInstance` method to initialize the JavaScript (Node) SDK and instantiate an instance of the Optimizely client class that exposes API methods like the [Decide methods](docId\:OR0QUdFTq9bg4lGgOz-nH). Each client corresponds to the datafile representing the state of a project for a certain environment.

## Version

SDK v5.0.0 and higher

## Description

The `createInstance` method accepts a configuration object to configure Optimizely Feature Experimentation.

Some parameters are optional because the SDK provides a default implementation, but you may want to override these for your production environments. For example, you may want to override these to configure an [error handler](docId\:kj4xDRaFGIbKrvpDTLRjx) and [logger](docId\:AvdZUN4jGJ_xBdNF70N3l) to catch issues, an [event dispatcher](docId\:gYmD2N57Sg8x6PrHXHMzx) to manage network calls, and a [User Profile Service](docId\:xqhs03ITVz6rdU8RpiHRe) to ensure sticky bucketing.

## Parameters

The following are the required and optional properties of the config object:

| Parameter                             | Type                      | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| ------------------------------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| \`datafile\` \_optional\_             | string                    | The JSON string representing the project. Either \`sdkKey\` or \`datafile\` is required, but you can provide both. See the \[Examples]\(#examples) section.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| \`sdkKey\` \_optional\_               | string                    | The key associated with an environment in the project. Either \`sdkKey\` or \`datafile\` is required, but you can provide both. See the \[Examples]\(#examples) section.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| \`eventDispatcher\` \_optional\_      | object                    | An event dispatcher to manage network calls. An object with a \`dispatchEvent\` method.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| \`logger\` \_optional\_               | object                    | A logger implementation to log messages. An object with a \`log\` method.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| \`errorHandler \_optional\_           | object                    | An error handler object to handle errors. An object with a \`handleErro\`r method                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| \`userProfileService\` \_optional\_   | object                    | A user profile service. An object with \`lookup\` and \`save\` methods.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| \`jsonSchemaValidator\` \_optional\_  | object                    | To perform JSON schema validation on datafiles, import the validator from \`'@optimizely/optimizely-sdk/dist/optimizely.json\_schema\_validator.min.js'\`, and pass it as this initialization option. Skipping JSON schema validation enhances performance during initialization.                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| \`datafileOptions\` \_optional\_      | object                    | Object with configuration for automatic datafile management. Can have \`autoUpdate\` (boolean), \`urlTemplate\` (string), and \`updateInterval\` (number) properties. In SDK versions >= 5.4.0 and \\\< 6.0.0, can have a \`customHeaders\` property.                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| \`datafileAccessToken\` \_optional\_  | string                    | Use an access token (with an \`sdkKey\`) to fetch the datafile from an authenticated endpoint. Find your datafile access token in the Optimizely app at **Settings > Environments**. Select your secure environment, and copy the **Datafile access token**. See the \[Use authenticated datafile in a secure environment]\(#use-authenticated-datafile-in-a-secure-environment) section.                                                                                                                                                                                                                                                                                                                          |
| \`defaultDecideOptions\` \_optional\_ | Array                     | Array of \`OptimizelyDecideOption\` enums. When the Optimizely client is constructed with this parameter, it sets default decide options which are applied to all the Decide calls made during the lifetime of the Optimizely client. Additionally, you can pass options to individual Decide methods (does not override defaults). For example code, see \[OptimizelyDecideOption]\(https\://docs.developers.optimizely.com/feature-experimentation/docs/decide-methods-javascript-node#optimizelydecideoption).                                                                                                                                                                                                  |
| \`ODPManager\`                        | \`OptimizelySdkSettings\` | Contains the logic supporting Real-Time Audiences for Feature Experimentation, including audience segments and sending events. You must configure this parameter to use Real-Time Audiences. The JavaScript (Node) SDK enables the Real-Time Audiences methods by default. But, the methods do nothing unless you have enabled and configured \[Real-Time Audiences for Feature Experimentation]\(https\://docs.developers.optimizely.com/feature-experimentation/docs/real-time-audiences-for-feature-experimentation). To optionally disable Real-Time Audiences completely, see \[OdpManager]\(https\://docs.developers.optimizely.com/feature-experimentation/docs/initialize-sdk-javascript-node#odpmanager). |

## Returns

Instantiates an instance of the Optimizely client class.

## Examples

In the JavaScript (Node) SDK, you can provide a `sdkKey` or `datafile` or both.

- **When initializing with just the SDK key** – The SDK polls for datafile changes in the background at regular intervals.
- **When initializing with just the datafile** – The SDK does NOT poll for datafile changes in the background.
- **When initializing with both the SDK key and datafile** – The SDK uses the given datafile and start polling for datafile changes in the background.

### Instantiate using SDK Key

In the JavaScript (Node) SDK, you only need to pass the SDK key value to instantiate a client. Whenever the experiment configuration changes, the SDK handles the change for you.

Include `sdkKey` as a string property in the options object you pass to the `createInstance` method.

```javascript
const { createInstance } = require('@optimizely/optimizely-sdk');

const optimizely = createInstance({
  sdkKey: 'YOUR_SDK_KEY', // Provide the sdkKey of your desired environment here
});
```

When you provide the `sdkKey`, the SDK instance downloads the datafile associated with that `sdkKey`. When the download completes, the SDK instance updates itself to use the downloaded datafile. You can use the `onReady` method to wait for the datafile to be downloaded before using the instance.

```javascript
const { createInstance } = require('@optimizely/optimizely-sdk');
const optimizely = createInstance({
  sdkKey: 'YOUR_SDK_KEY', // Provide the sdkKey of your desired environment here
});

if (!optimizely) {
  // there was an error creating the instance, handle error
} else {
  // Use optimizelyClient
  optimizely.onReady().then(({ success, reason }) => {
    if (success) {
      // optimizelyClientInstance is ready to use, with datafile downloaded from the
      // Optimizely CDN
    } else {
      // this optimizely client instance cannot be used
      console.log(`client initialization unsuccessful, reason: ${reason}`);
    }
  });
}
```

### Instantiate using datafile

To instantiate using datafile, first you must get a copy of the datafile from Optimizely's server. In The following example, this example demonstrates fetching the datafile using the `node-fetch@2` library.

```javascript
// Minimal client
const { createInstance } = require('@optimizely/optimizely-sdk');
const fetch = require('node-fetch');

// Replace YOUR_SDK_KEY to get the datafile
const sdkKey = 'YOUR_SDK_KEY';
const DATAFILE_URL = `https://cdn.optimizely.com/datafiles/${sdkKey}.json`;
const response = await fetch(DATAFILE_URL);
const datafile = await response.json();

const optimizely = createInstance({
  datafile
});

if (!optimizely) {
  // there was an error creating the instance, handle error
} else {
  // Use optimizelyClient to run experiments
}
```

If you do not pass in an SDK key, the Optimizely Client will not automatically sync newer datafile versions. Any time you retrieve an updated datafile, just re-instantiate the same client.

For simple applications, all you need to provide to instantiate a client is a datafile specifying the project configuration for a given environment. For most advanced implementations, you should [customize the logger](docId\:AvdZUN4jGJ_xBdNF70N3l) or [error handler](docId\:kj4xDRaFGIbKrvpDTLRjx) for your specific requirements.

## Notes

### Customize datafile management behavior

To customize datafile management behavior, provide a `datafileOptions` object property inside the `options` object passed to `createInstance`. The table lists the supported customizable options.

| Option           | Type                               | Description                                                                                                                                                                                                  |
| ---------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `autoUpdate`     | boolean                            | When true, and `sdkKey` was provided in `createInstance` options, automatic updates are enabled on this instance. The default value is `true`.                                                               |
| `updateInterval` | number                             | When automatic updates are enabled, this controls the update interval. The unit is milliseconds. The minimum allowed value is 1000 (1 second). The default value is 300000 milliseconds (5 minutes).         |
| `urlTemplate`    | string                             | A format string used to build the URL from which the SDK will request datafiles. Instances of `%s` is replaced with the `sdkKey`. When not provided, the SDK will request datafiles from the Optimizely CDN. |
| `customHeaders`  | `object (Record<string>,<string>)` | Lets you pass custom HTTP headers while fetching the datafile. Available in Javascript (Node) SDK versions >= 5.4.0 and \< 6.0.0.                                                                            |

The following example shows how to customize datafile management behavior:

```javascript
const { createInstance } = require('@optimizely/optimizely-sdk');

const optimizely = createInstance({
  sdkKey: '<YOUR_SDK_KEY>',
  datafileOptions: {
    autoUpdate: true,
    updateInterval: 600000, // 10 minutes in milliseconds
    urlTemplate: 'http://localhost:5000/datafiles/%s.json',
    // Available  in Javascript (Node) SDK versions >= 5.4.0 and < 6.0.0.
    customHeaders: {
      'User-Agent': 'optimizely-sdk/5.4.0 (+https://github.com/optimizely/javascript-sdk)',
    },
  },
});
```

### `onReady` details

Use the `onReady` method to wait until the download is complete and the SDK is ready to use.

The `onReady` method returns a Promise representing the initialization process. `onReady` accepts an optional timeout argument (defined in milliseconds) that controls the maximum duration that the returned Promise remains in the pending state. If timeout is not provided, it defaults to 30 seconds.

```javascript
const { createInstance } = require('@optimizely/optimizely-sdk');
const optimizely = createInstance({
  sdkKey: 'YOUR_SDK_KEY',
});

if (!optimizely) {
  // there was an error creating the instance, handle error
} else {
  // Use optimizelyClient
  optimizely.onReady().then(result => {
    // Returned Promise is fulfilled with a result object
    console.log(result.success); // true if the instance fetched a datafile and is now ready to use
    console.log(result.reason); // If success is false, reason contains an error message
  });

  // Provide a timeout in milliseconds - promise will resolve if the datafile still is not available after the timeout
  optimizely.onReady({ timeout: 5000 }).then(result => {
    // Returned Promise is fulfilled with a result object
    console.log(result.success); // true if the instance fetched a datafile and is now ready to use
    console.log(result.reason); // If success is false, reason contains an error message
  });
};
```

The Promise returned from the `onReady` method is fulfilled with a result object containing a boolean success property.

When the `success` property is `true`, the instance is ready to use with a valid datafile. When the success property is `false`, there is also a `reason`string property describing the failure. Failure can be caused by expiration of the timeout, network error, unsuccessful HTTP response, datafile validation error, or the instance's`close` method being called.

### Set a fallback datafile

If you provide a sdkKey and a static fallback datafile for initialization, the SDK uses the fallback datafile immediately if it is valid while simultaneously downloading the datafile associated with the sdkKey. After the download completes, if the downloaded datafile is valid and has a more recent revision than the fallback datafile, the SDK updates the instance to use the downloaded datafile.

```javascript
const { createInstance } = require('@optimizely/optimizely-sdk');
const datafile = '{"version": "4", "rollouts": [], "typedAudiences": [], "anonymizeIP": false, "projectId": "12345", "variables": [], "featureFlags": [], "experiments": [], "audiences": [], "groups": [], "attributes": [], "botFiltering": false, "accountId": "12345", "events": [], "revision": "1"}'; 
const optimizely = createInstance({
  sdkKey: '<Your_SDK_Key>',
  datafile,
});
// optimizelyClientInstance can be used immediately with the given datafile, but
// will download the latest datafile and update itself
```

## Dispose of the client

For effective resource management with the Optimizely JavaScript (Node) SDK, you must properly close the Optimizely client instance when it is no longer needed. This is done by calling `optimizely.close()`.

The `.close()` method ensures that the processes and queues associated with the instance are properly released. This is essential for preventing memory leaks and ensuring that the application runs efficiently, especially in environments where resources are limited or in applications that create and dispose of many instances over their lifecycle.

See [Close Optimizely on application exit](docId\:Tq8vbUUzK26SSvlL34DWu).

## Use authenticated datafile in secure environment

You can fetch the Optimizely datafile from an authenticated endpoint using a server-side (only) SDK, like the JavaScript (Node) SDK.

To use an [authenticated datafile](docId\:YpSOMYlWkUccLCL-uB-ZE), download your Optimizely environment's access token from the Optimizely app at **Settings > Environments**. Select your secure environment, and copy the **Datafile access token**. The following example shows how to initialize the Optimizely client using an access token and `sdkKey`, enabling the client to fetch the authenticated datafile and complete initialization.

```javascript
import { createInstance } from '@optimizely/optimizely-sdk';

// fetch the datafile from an authenticated endpoint
const optimizely = createInstance({
  sdkKey: 'YOUR_SDK_KEY',
  datafileOptions: {
    datafileAccessToken: 'YOUR_DATAFILE_ACCESS_TOKEN',
  },
});
```

## `OdpManager`

The `OdpManager` contains the logic supporting Real-Time Audiences for Feature Experimentation, including audience segments and sending ODP events. You must configure this parameter to use Real-Time Audiences.

The JavaScript (Node) SDK enables the Real-Time Audiences methods by default. But, the methods do nothing unless you have enabled and configured [Real-Time Audiences for Feature Experimentation](docId:6UBBxxRv331nBIVZ2lun8).

If necessary, to disable Real-Time Audiences altogether, set `disabled: true`. See the following sample code for information:

```javascript
const { createInstance } = require('@optimizely/optimizely-sdk');

const optimizely = createInstance({
  sdkKey: 'YOUR_SDK_KEY',
  odpOptions: {
    disabled: true,
  },
});
```

The following settings are optionally configurable when the JavaScript (Node) SDK is initialized:

- **ODP SegmentsCache size** – `segmentsCacheSize`
  - **Default** – 10,000
  - Set to 0 to disable caching.
- **ODP SegmentsCache timeout** (in seconds) – `segmentsCacheTimeout`
  - **Default** – 600 secs (10 minutes)
  - Set to 0 to disable timeout (never expires).
- **ODP enable** – `disabled`
  - **Default** – false (enabled)
  - The JavaScript (Node) SDK returns or logs an `odpNotEnabled` error when ODP is disabled and its features are requested.

Initialize the JavaScript (Node) SDK with Real-Time Audiences and custom settings:

```javascript
const { createInstance } = require('@optimizely/optimizely-sdk');

const optimizely = createInstance({
  sdkKey: 'YOUR_SDK_KEY',
  odpOptions: {
    // disabled: false,  // change to true to disable
    eventApiTimeout: 1000,
    eventQueueSize: 1,
    // eventRequestHandler: new BrowserRequestHandler(),
    // eventManager: new OdpEventManager(),
    segmentsApiTimeout: 1000,
    segmentsCacheSize: 10,
    segmentsCacheTimeout: 1000,
    // segmentsCache: new ICache<string, string[]>(),
    // segmentsRequestHandler: new BrowserRequestHandler(),
    // segmentManager: new OdpSegmentManager(),
    
  },
});
```

### Customize `OdpManager`

Using the parameters in `odpOptions`, you can customize the behavior of the ODP event and segment managers, even going as far as being able to replace them with your own implementations if desired.

The following code example shows `odpOptions` with a custom `eventManager`:

```javascript
odpOptions: {  
  // ...
  eventManager: new OdpEventManager({  
    odpConfig, // new OdpConfig()  
    apiManager, // new OdpEventApiManager()  
    logger, // new LogHandler()  
    clientEngine: 'javascript-sdk',  
    clientVersion: '5.0.0',  
    batchSize: 10, 
    flushInterval: 2000,
  }),  
},
```

### Customize the `OdpEventApiManager`

```typescript
export interface IOdpEventApiManager {  
  sendEvents(apiKey: string, apiHost: string, events: OdpEvent[]): Promise<boolean>;  
}
```

The following code example shows `odpOptions` with a custom `segmentManager`:

```javascript
odpOptions: {  
  // ...
  segmentManager: new OdpSegmentManager(  
    odpConfig, // new OdpConfig()  
    new BrowserLRUCache<string, string[]>({  
      maxSize: 2,  
      timeout: 4000,  
    }), // new ICache<string, string[]>()  
    segmentApiManager, // new IOdpSegmentApiManager()  
  ),  
},
```

### Custom cache

You can provide a custom cache, which is used to store the [`fetch_qualified_segments`](https://docs.developers.optimizely.com/feature-experimentation/docs/real-time-segments-for-feature-experimentation-segment-qualification-methods-javascript-node) results. To provide a custom cache, you should implement the following interface:

**Segments Cache Interface**

```typescript
export interface ICache<K, V> {
  lookup(key: K): V | null;
  save({ key, value }: { key: K; value: V }): void;
  reset(): void;
}
```

**Custom Segments Cache Implementation example from LRUCache implementation**

```typescript
export class LRUCache<K, V> implements ICache<K, V> {
  private _map: Map<K, CacheElement<V>> = new Map();
  private _maxSize; // Defines maximum size of _map
  private _timeout; // Milliseconds each entry has before it becomes stale

  get map(): Map<K, CacheElement<V>> {
    return this._map;
  }

  get maxSize(): number {
    return this._maxSize;
  }

  get timeout(): number {
    return this._timeout;
  }

  constructor({ maxSize, timeout }: LRUCacheConfig) {
    const logger = getLogger();

    logger.debug(`Provisioning cache with maxSize of ${maxSize}`);
    logger.debug(`Provisioning cache with timeout of ${timeout}`);

    this._maxSize = maxSize;
    this._timeout = timeout;
  }

  public lookup(key: K): V | null {
    if (this._maxSize <= 0) {
      return null;
    }

    const element: CacheElement<V> | undefined = this._map.get(key);

    if (!element) return null;

    if (element.is_stale(this._timeout)) {
      this._map.delete(key);
      return null;
    }

    this._map.delete(key);
    this._map.set(key, element);

    return element.value;
  }

  public save({ key, value }: { key: K; value: V }): void {
    if (this._maxSize <= 0) return;

    const element: CacheElement<V> | undefined = this._map.get(key);
    if (element) this._map.delete(key);
    this._map.set(key, new CacheElement(value));

    if (this._map.size > this._maxSize) {
      const firstMapEntryKey = this._map.keys().next().value;
      this._map.delete(firstMapEntryKey);
    }
  }

  public reset(): void {
    if (this._maxSize <= 0) return;

    this._map.clear();
  }

  public peek(key: K): V | null {
    if (this._maxSize <= 0) return null;

    const element: CacheElement<V> | undefined = this._map.get(key);

    return element?.value ?? null;
  }
}
```

## Source files

The source code files containing the implementation for the JavaScript (Node) SDK are available on [GitHub](https://github.com/optimizely/javascript-sdk/blob/master/lib/optimizely/index.ts).
