---
title: Migrate Your Feature Flags from Statsig
description: Learn how to migrate feature flags from Statsig to Datadog Feature Flags.
breadcrumbs: >-
  Docs > Feature Flags > Feature Flags Guides > Migrate Your Feature Flags from
  Statsig
---

> For the complete documentation index, see [llms.txt](https://docs.datadoghq.com/llms.txt).

# Migrate Your Feature Flags from Statsig

{% callout %}
# Important note for users on the following Datadog sites: app.ddog-gov.com, us2.ddog-gov.com

{% alert level="danger" %}
This product is not supported for your selected [Datadog site](https://docs.datadoghq.com/getting_started/site.md). ({% placeholder "user-datadog-site-name" /%}).
{% /alert %}

{% /callout %}

## Overview{% #overview %}

This guide outlines the process for migrating your feature flagging logic from Statsig to [Datadog Feature Flags](https://docs.datadoghq.com/feature_flags.md). It covers conceptual mappings, SDK installation, initialization, and flag evaluation.

## Summary checklist{% #summary-checklist %}

- Replace `@statsig/js-client` with `@datadog/openfeature-browser`.
- Swap `statsig.initialize` with `OpenFeature.setProviderAndWait`.
- Convert `checkGate` to `client.getBooleanValue`.
- Convert `getDynamicConfig` to `client.getObjectValue` or `client.getStringValue`.
- Convert `getLayer` to `client.getObjectValue` and dereference fields from the returned JSON object.
- Use `targetingKey` in the context to identify users and drive percentage-based randomization.
- Recreate your Statsig flags in Datadog.
- For server-side apps, use `@openfeature/server-sdk` and pass a per-request evaluation context instead of a single global context.

## Recreate flags in Datadog{% #recreate-flags-in-datadog %}

Before you switch SDK calls in your application, recreate your Statsig gates, dynamic configs, and layers as flags in Datadog. In the Datadog UI, go to **Software Delivery** > **Feature Flags** and create flags that match your Statsig keys, variant types, and targeting rules.

## Conceptual mapping{% #conceptual-mapping %}

The core concepts between Statsig and Datadog are similar, but the terminology differs slightly.

| Statsig Concept      | Datadog Concept                         | Notes                                                                                                                                                                                                                                  |
| -------------------- | --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Feature Gate**     | **Feature Flag** (Boolean)              | Basic on/off toggles.                                                                                                                                                                                                                  |
| **Dynamic Config**   | **Feature Flag** (JSON/String variants) | Flags in Datadog can return strings, JSON, or numbers, covering Statsig's Dynamic Config use cases.                                                                                                                                    |
| **Layer**            | **Feature Flag** (JSON variant)         | Use a JSON-valued flag and read fields from the returned object, similar to dereferencing values from a Statsig layer.                                                                                                                 |
| **Experiment**       | **Feature Flag** (with targeting)       | A Datadog flag can be configured with percentage-based rollouts and specific targeting rules to run experiments. Connect flags to [Datadog Experiments](https://docs.datadoghq.com/experiments.md) to measure impact on user outcomes. |
| **User/StatsigUser** | **Evaluation Context**                  | The context (attributes) passed to the SDK to evaluate flags.                                                                                                                                                                          |

## Installation{% #installation %}

Datadog designs its feature flagging SDKs for use with [OpenFeature](https://openfeature.dev/). This provides a vendor-neutral API while using Datadog as the underlying provider.

Remove Statsig:

```bash
npm uninstall @statsig/js-client
# or
yarn remove @statsig/js-client
```

Install Datadog and OpenFeature:

```bash
npm install @datadog/openfeature-browser @openfeature/web-sdk @openfeature/core
# or
yarn add @datadog/openfeature-browser @openfeature/web-sdk @openfeature/core
```

**Note**: For React applications, also install `@openfeature/react-sdk`. See [React Feature Flags](https://docs.datadoghq.com/feature_flags/client/react.md). For server-side implementations, see the Server-side and dynamic context section, or [Server-Side Feature Flags](https://docs.datadoghq.com/feature_flags/server.md) for other languages.

## Initialization{% #initialization %}

You must replace the `statsig.initialize()` call with the OpenFeature provider setup. Pass the evaluation context to `setProviderAndWait` at registration time so flags are evaluated for the correct user from the start.

### Statsig (old){% #statsig-old %}

```javascript
import { StatsigClient } from '@statsig/js-client';

const client = new StatsigClient('client-sdk-key', { userID: 'user-123' });
await client.initializeAsync();
```

### Datadog (new){% #datadog-new %}

```javascript
import { DatadogProvider } from '@datadog/openfeature-browser';
import { OpenFeature } from '@openfeature/web-sdk';
```

```javascript
// Configure the Datadog provider
const provider = new DatadogProvider({
  clientToken: '<CLIENT_TOKEN>',
  applicationId: '<APPLICATION_ID>',
  site: 'datadoghq.com', // or datadoghq.eu, etc.
  env: 'production', // Environment from which to fetch flag configurations
});

// Set the evaluation context and register the provider together
const evaluationContext = {
  targetingKey: 'user-123', // Identifies the user and drives percentage-based randomization
  email: 'employee@company.com',
  plan: 'premium',
};

await OpenFeature.setProviderAndWait(provider, evaluationContext);
```

{% alert level="info" %}
The `targetingKey` is used as the randomization subject for percentage-based targeting. When a flag targets a percentage of subjects (for example, 50%), the `targetingKey` determines which bucket a user falls into. Users with the same `targetingKey` always receive the same variant for a given flag.
{% /alert %}

For more information on creating client tokens and application IDs, see [API and Application Keys](https://docs.datadoghq.com/account_management/api-app-keys.md).

## Evaluate flags (check gates){% #evaluate-flags-check-gates %}

Replace `checkGate` calls with OpenFeature's `getBooleanValue`.

### Statsig (old){% #statsig-old-1 %}

```javascript
const isEnabled = client.checkGate('new_homepage_design');

if (isEnabled) {
  // Show new design
} else {
  // Show old design
}
```

### Datadog (new){% #datadog-new-1 %}

```javascript
const client = OpenFeature.getClient();

// The second argument is the fallback value (default) if the flag fails to fetch
const isEnabled = client.getBooleanValue('new_homepage_design', false);

if (isEnabled) {
  // Show new design
} else {
  // Show old design
}
```

## Get configuration (dynamic configs){% #get-configuration-dynamic-configs %}

If you were using `getDynamicConfig` or `getExperiment` to retrieve non-Boolean values (strings, JSON, numbers), use the appropriate typed method in OpenFeature.

### Statsig (old){% #statsig-old-2 %}

```javascript
const config = client.getDynamicConfig('banner_config');
const title = config.get('title', 'Welcome');
```

### Datadog (new){% #datadog-new-2 %}

```typescript
const client = OpenFeature.getClient();

// Assuming your Datadog flag 'banner_config' returns a JSON object variant
const bannerConfig = client.getObjectValue<{ title: string }>('banner_config', { title: 'Welcome' });
const title = bannerConfig.title;
```

## Map layers to JSON object flags{% #map-layers-to-json-object-flags %}

Statsig layers group related parameters under one evaluation. In Datadog, use a JSON-valued flag and read the fields you need from the returned object.

### Statsig (old){% #statsig-old-3 %}

```javascript
const layer = client.getLayer('user_promo_experiments');
const promoTitle = layer.get('title', 'Welcome to Statsig!');
const discount = layer.get('discount', 0.1);
```

### Datadog (new){% #datadog-new-3 %}

```typescript
const client = OpenFeature.getClient();

const promoConfig = client.getObjectValue<{ title: string; discount: number }>('user_promo_experiments', {
  title: 'Welcome!',
  discount: 0.1,
});
const promoTitle = promoConfig.title;
const discount = promoConfig.discount;
```

## Update user context after login{% #update-user-context-after-login %}

Statsig updates user context using `updateUser`. In OpenFeature and Datadog, update the context after initialization with `OpenFeature.setContext()`, for example after a user logs in.

### Statsig (old){% #statsig-old-4 %}

```javascript
await client.updateUserAsync({
  userID: 'user-456',
  email: 'employee@company.com',
  custom: { plan: 'premium' },
});
```

### Datadog (new){% #datadog-new-4 %}

```javascript
// Update the context for all future flag evaluations
await OpenFeature.setContext({
  targetingKey: 'user-456', // Identifies the user and drives percentage-based randomization
  email: 'employee@company.com',
  plan: 'premium',
});
```

## Tracking and exposure{% #tracking-and-exposure %}

In Statsig, checking a gate automatically logs an exposure.

In Datadog, flag telemetry falls into two categories:

**Exposure logging** records that a subject received a specific flag variant. Each exposure event includes the flag key, variant served, and evaluation context. Use exposure data to analyze experiment results and feature adoption.

**Evaluation logging** records how often each variant is returned. Client SDKs send aggregated evaluation counts by default. Server SDKs emit the `feature_flag.evaluations` metric only after you enable evaluation logging.

1. **Client SDKs**: Exposure logging is enabled by default. The SDK sends exposure events to the exposures intake. You can view them in the **Feature Flags** list. Set `enableExposureLogging: false` in the `DatadogProvider` config if you do not need exposure tracking.

{% alert level="warning" %}
Setting `enableRumFeatureFlagTracking` to `true` can impact [RUM](https://docs.datadoghq.com/real_user_monitoring.md) costs, as it adds flag evaluations to RUM events. Both `enableExposureLogging` and `enableRumFeatureFlagTracking` are on by default for client SDKs.
{% /alert %}
**Server SDKs**: Exposure logging is on by default. Evaluation logging is off by default. To send evaluation metrics from server SDKs, enable OpenTelemetry metrics (for example, `DD_METRICS_OTEL_ENABLED=true`) and follow the language-specific guidance in [Server-Side Feature Flags](https://docs.datadoghq.com/feature_flags/server.md).
## Server-side and dynamic context{% #server-side-and-dynamic-context %}

The previous sections cover browser and client-side migration, where the evaluation context is typically static for the length of a user's session. Server-side applications use a different SDK and authenticate with a Datadog API key instead of a client token. They also typically build a new evaluation context for each incoming request.

Configure the required environment variables before initializing the server SDK:

```bash
DD_API_KEY=<DATADOG_API_KEY>
DD_SITE=<DATADOG_SITE>
DD_ENV=<ENVIRONMENT_NAME>
```

See [Server-Side Feature Flags](https://docs.datadoghq.com/feature_flags/server.md) for the full list of Agent and application configuration options.

Install the server-side SDK. This example uses the [Node.js Feature Flags SDK](https://docs.datadoghq.com/feature_flags/server/nodejs.md):

```bash
npm install dd-trace @openfeature/server-sdk
```

Register the provider through the Datadog tracer:

```javascript
import tracer from 'dd-trace';
import { OpenFeature } from '@openfeature/server-sdk';

tracer.init();

await OpenFeature.setProviderAndWait(tracer.openfeature);
```

### Statsig (old){% #statsig-old-5 %}

```javascript
// The Statsig server SDK takes the user in each call
const isEnabled = statsig.checkGate(user, 'new_homepage_design');
```

### Datadog (new){% #datadog-new-5 %}

```javascript
const client = OpenFeature.getClient();

app.get('/my-endpoint', async (req, res) => {
  const evaluationContext = {
    targetingKey: req.session?.userID ?? 'unknown',
  };

  const isEnabled = await client.getBooleanValue('new_homepage_design', false, evaluationContext);
  res.send(isEnabled ? 'New design' : 'Old design');
});
```

The browser SDK uses whatever evaluation context is set for every flag evaluation. You can update that context with `OpenFeature.setContext()` when the user logs in or their attributes change. The server SDK instead passes a new evaluation context into each flag evaluation call, since one process handles many different users.

For other server languages, see [Server-Side Feature Flags](https://docs.datadoghq.com/feature_flags/server.md).
