> ## Documentation Index
> Fetch the complete documentation index at: https://launchdarkly.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrating from Statsig to LaunchDarkly Experimentation

This guide explains how to migrate your Statsig experiment implementation to LaunchDarkly Experimentation. It focuses on experiments and metrics, covering the conceptual differences between the two platforms and showing side-by-side SDK code comparisons for Node.js (server-side) and JavaScript.

## Migrate with a coding agent

LaunchDarkly provides agent instructions that manage the entire migration process for you, including:

* Implementing LaunchDarkly SDKs
* Instrumenting flag evaluations and metric events
* Importing flag objects and targeting rules
* Importing metric definitions

To use the migration agent, paste this prompt into your AI tool:

<CodeGroup>
  ```text title="Agent prompt" lines wrap theme={null}
  Read the README at https://github.com/launchdarkly-labs/statsig-to-ld and follow the Agent Instructions section to help me migrate from Statsig to LaunchDarkly.
  ```
</CodeGroup>

You can view the full migration tool in the [Statsig to LaunchDarkly CLI repository](https://github.com/launchdarkly-labs/statsig-to-ld).

## Migration overview

To migrate manually, or to complete one migration step at a time, follow the steps in this guide.

This guide covers the following SDKs:

* [Node.js (server-side) SDK](/docs/sdk/server-side/node-js)
* [JavaScript SDK](/docs/sdk/client-side/javascript)

The steps in this guide include:

1. [Implementing LaunchDarkly SDKs](#step-1-implement-launchdarkly-sdks)
2. [Recreating flags in LaunchDarkly](#step-2-recreate-flags-in-launchdarkly)
3. [Migrating Statsig metrics to LaunchDarkly metrics](#step-3-migrate-statsig-metrics-to-launchdarkly-metrics)
4. [Creating experiments in LaunchDarkly](#step-4-set-up-experiments-in-launchdarkly)

This guide focuses on information specific to migrating from Statsig. For a general overview of what to consider when migrating to LaunchDarkly, read [Migrating your existing feature flag solution to LaunchDarkly](/docs/guides/account/migrating-solutions).

## How LaunchDarkly experiments differ from Statsig experiments

The most important conceptual difference is that LaunchDarkly experiments are built on top of feature flags. In Statsig, an experiment is a standalone entity you query directly with `getExperiment()`. In LaunchDarkly, you create a feature flag whose variations represent your experiment arms, then create an experiment on top of that flag in the LaunchDarkly UI. Your SDK code evaluates the flag, and LaunchDarkly records the assignment automatically.

This means a LaunchDarkly experiment flag works like any other flag in your codebase. You call `variation()`, or a typed variant like `stringVariation()` or `jsonVariation()`, and the SDK handles assignment, bucketing, and exposure tracking for you.

### Mapping terms between LaunchDarkly and Statsig

<table>
  <thead>
    <tr>
      <th>Statsig</th>
      <th>LaunchDarkly</th>
      <th>Notes</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>Experiment</td>
      <td>[Experiment](/docs/home/experimentation)</td>
      <td>LaunchDarkly experiments are flag-based</td>
    </tr>

    <tr>
      <td>Experiment parameter</td>
      <td>[Flag variation](/docs/home/flags/variations)</td>
      <td>Each arm of the experiment is a flag variation</td>
    </tr>

    <tr>
      <td>Feature gate</td>
      <td>[Boolean feature flag](/docs/home/flags/types#boolean-flags)</td>
      <td>Two variations of true or false</td>
    </tr>

    <tr>
      <td>Dynamic config</td>
      <td>Multivariate feature flag</td>
      <td>Can use [number](/docs/home/flags/types#number-flags), [string](/docs/home/flags/types#string-flags), or [JSON](/docs/home/flags/types#json-flags) variations</td>
    </tr>

    <tr>
      <td>Layer</td>
      <td>[Experiment layer](/docs/home/experimentation/mutually-exclusive)</td>
      <td>Used in mutually exclusive experiments</td>
    </tr>

    <tr>
      <td><code>StatsigUser</code></td>
      <td><code>LDContext</code></td>
      <td>Refer to [User and context mapping](#user-and-context-mapping)</td>
    </tr>

    <tr>
      <td><code>userID</code></td>
      <td><code>LDContext.key</code></td>
      <td>The context key. Together, kind and key uniquely identify a LaunchDarkly [context](/docs/home/flags/contexts).</td>
    </tr>

    <tr>
      <td><code>custom</code> attributes</td>
      <td>Top-level [context attributes](/docs/home/flags/context-attributes)</td>
      <td>LaunchDarkly does not nest [custom attributes](/docs/home/flags/custom-attributes)</td>
    </tr>

    <tr>
      <td><code>customIDs</code></td>
      <td>Multi-context (<code>kind: 'multi'</code>)</td>
      <td>To learn more, read [Multi-contexts](#multi-contexts)</td>
    </tr>

    <tr>
      <td><code>logEvent()</code></td>
      <td><code>track()</code></td>
      <td>Used to record [metric events](/docs/home/metrics/metric-events)</td>
    </tr>

    <tr>
      <td>Server Secret Key</td>
      <td>[SDK key](/docs/home/account/environment/keys)</td>
      <td>Server-side only. Do not expose in code.</td>
    </tr>

    <tr>
      <td>Client SDK Key</td>
      <td>[Client-side ID](/docs/home/account/environment/keys)</td>
      <td>Safe to expose in browser code</td>
    </tr>

    <tr>
      <td>Console metric</td>
      <td>[Metric](/docs/home/metrics)</td>
      <td>Several [metric types available](/docs/home/metrics/choose)</td>
    </tr>
  </tbody>
</table>

## Migration strategy

We recommend running Statsig and LaunchDarkly in parallel during your migration rather than switching over all at once. This lets you validate that bucketing and results are consistent before fully cutting over.

We suggest this approach:

1. **Set up LaunchDarkly**: Create your experiment flags and metrics in LaunchDarkly.
2. **Evaluate both SDKs**: In your application, call both `Statsig.getExperiment()` and `client.variation()`. Log both results temporarily to verify consistent assignments.
3. **Track in both systems**: Call both `Statsig.logEvent()` and `client.track()` so metric data accumulates in LaunchDarkly while you validate.
4. **Cut over**: When you're confident the LaunchDarkly experiment is running correctly, remove the Statsig SDK calls and shut down the Statsig client.

## Step 1: Implement LaunchDarkly SDKs

LaunchDarkly offers over 25 server-side and client-side SDKs. To begin, decide on which LaunchDarkly SDKs you want to use.

The following sections give examples of how to install, initialize, and shut down two LaunchDarkly SDKs. For a full understanding of how to implement an SDK, [select an SDK from the list](/docs/sdk) and read its reference topic.

### Installation

To begin, replace your Statsig SDK dependency with the appropriate LaunchDarkly SDK. Here are examples for Node.js (server-side) and JavaScript:

<CodeGroup>
  ```bash title="Node.js (server-side)" lines wrap theme={null}
  # Remove
  npm uninstall statsig-node

  # Add
  npm install @launchdarkly/node-server-sdk
  ```

  ```bash title="JavaScript" lines wrap theme={null}
  # Remove
  npm uninstall @statsig/js-client

  # Add
  npm install launchdarkly-js-client-sdk
  ```
</CodeGroup>

### Initialization

Next, initialize your SDK. Here's a comparison of how the Node.js (server-side) and JavaScript SDKs are initialized in Statsig and LaunchDarkly:

<CodeGroup>
  ```ts title="Node.js (server-side)" lines wrap theme={null}
  // Statsig
  import Statsig from 'statsig-node';

  await Statsig.initialize('server-secret-key', {
    environment: { tier: 'staging' },
  });

  // LaunchDarkly
  import * as ld from '@launchdarkly/node-server-sdk';

  const client = ld.init('sdk-key');
  await client.waitForInitialization();
  ```

  ```js title="JavaScript" expandable lines wrap theme={null}
  //Statsig
  import { StatsigClient } from '@statsig/js-client';

  const statsig = new StatsigClient('client-sdk-key', {
    userID: 'user-123',
    email: 'user@example.com',
  });
  await statsig.initializeAsync();

  //LaunchDarkly
  import * as ld from 'launchdarkly-js-client-sdk';

  const context: ld.LDContext = {
    kind: 'user',
    key: 'user-123',
    email: 'user@example.com',
  };

  const client = ld.initialize('client-side-id', context);
  await client.waitForInitialization();
  ```
</CodeGroup>

The `sdk-key` or `client-side-id` credential corresponds to a specific environment. For example, "production" or "staging." Select the correct credential from your environment's [SDK keys page](/docs/home/account/environment/keys).

### Shutdown

Here's a comparison of how to shut down the Node.js (server-side) and the JavaScript SDKs in Statsig and LaunchDarkly:

<CodeGroup>
  ```ts title="Shutting down" lines wrap theme={null}
  //Statsig
  await Statsig.shutdown();

  //LaunchDarkly
  await client.close();
  ```
</CodeGroup>

### User and context mapping

LaunchDarkly contexts are data objects that represent users, devices, organizations, and other entities. LaunchDarkly represents contexts using an `LDContext` object where Statsig uses a `StatsigUser`.

The main differences are:

<table>
  <thead>
    <tr>
      <th scope="col">Statsig</th>
      <th scope="col">LaunchDarkly</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>userID</code></td>
      <td><code>key</code>.</td>
    </tr>

    <tr>
      <td>User object has no context <code>kind</code></td>

      <td>
        Include <code>kind</code>, typically <code>'user'</code>.
      </td>
    </tr>

    <tr>
      <td>
        First-class fields include <code>userID</code>, <code>email</code>, <code>ip</code>, and <code>userAgent</code>.
        Other attributes live under <code>custom</code>.
      </td>

      <td>
        Custom attributes are top-level on <code>LDContext</code>, not nested under <code>custom</code>. Map Statsig <code>custom</code> fields to top-level attributes.
      </td>
    </tr>
  </tbody>
</table>

<CodeGroup>
  ```ts title="Example user object" expandable lines wrap theme={null}
  //Statsig
  const user = {
    userID: 'user-123',
    email: 'user@example.com',
    custom: {
      country: 'US',
      plan: 'enterprise',
      company_id: 'acme-corp',
    },
  };

  //LaunchDarkly
  const context: ld.LDContext = {
    kind: 'user',
    key: 'user-123',
    email: 'user@example.com',
    country: 'US',
    plan: 'enterprise',
    company_id: 'acme-corp',
  };
  ```
</CodeGroup>

#### Multi-contexts

Statsig's `customIDs` field lets you associate a user with other entities, such as a company or device, for bucketing purposes. LaunchDarkly handles this with multi-contexts, where each entity is a separate context kind within a single `kind: 'multi'` object.

Here is a comparison of Statsig and LaunchDarkly multi-entity objects:

<CodeGroup>
  ```js title="Multi-context" expandable lines wrap theme={null}
  //Statsig
  const user = {
    userID: 'user-123',
    email: 'user@example.com',
    customIDs: {
      companyID: 'acme-corp',
    },
  };

  //LaunchDarkly
  const context: ld.LDContext = {
    kind: 'multi',
    user: {
      kind: 'user',
      key: 'user-123',
      email: 'user@example.com',
    },
    company: {
      kind: 'company',
      key: 'acme-corp',
    },
  };
  ```
</CodeGroup>

You can then target or bucket your experiment by either the `user` or `company` context kind in the LaunchDarkly UI.

## Step 2: Recreate flags in LaunchDarkly

To move gates and configs from Statsig, recreate them as LaunchDarkly flags. You can use one of three methods:

* create flags in the LaunchDarkly UI
* use the LaunchDarkly [REST API](/docs/api/feature-flags/create-a-feature-flag)
* use  an infrastructure as code method such as [Terraform](/docs/integrations/terraform)

Statsig concepts map to LaunchDarkly flags this way:

<table>
  <thead>
    <tr>
      <th scope="col">Statsig</th>
      <th scope="col">LaunchDarkly</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>
        <strong>Feature gates</strong> (boolean checks)
      </td>

      <td>
        <strong>Boolean flags</strong>
      </td>
    </tr>

    <tr>
      <td>
        <strong>Dynamic configs</strong>
      </td>

      <td>
        <strong>Multivariate flags</strong> (for scalar values) or <strong>JSON flags</strong> when the payload is structured JSON.
      </td>
    </tr>
  </tbody>
</table>

Treat experiments separately. There is no import path that recreates a Statsig experiment as a LaunchDarkly experiment. Instead, create a LaunchDarkly flag whose variations match your arms, then attach an experiment to that flag in the UI, as described in [Setting up experiments in LaunchDarkly](#step-4-set-up-experiments-in-launchdarkly).

Before recreating large sets of flags, audit your existing Statsig gates and configs for anything stale or no longer in use. Where possible, reuse the same flag keys in LaunchDarkly. LaunchDarkly keys may contain only letters, numbers, periods (`.`), underscores (`_`), and dashes (`-`). We recommend you rename them only when Statsig keys use other characters.

Statsig often models environments with targeting tiers or metadata on one object. LaunchDarkly gives each environment its own targeting for the same flag, and each environment uses SDK credentials. Create flags once per LaunchDarkly project, then configure each environment in the LaunchDarkly UI (or API) to match how Statsig behaved in dev, staging, and production.

To learn more, read [Creating flags](/docs/home/flags/create).

### Evaluating experiment variations

In Statsig, you call `getExperiment()` and then call `.get()` on the result to retrieve individual parameters. In LaunchDarkly, you call `variation()` directly on the client to get the variation value for the flag that backs the experiment.

LaunchDarkly offers two approaches for experiments with multiple parameters.

#### Option 1: String or boolean flag for a single parameter

Use a typed variation method when your experiment controls a single value.

<CodeGroup>
  ```ts title="Single parameter, Node.js (server-side)" lines wrap theme={null}
  //Statsig
  const experiment = Statsig.getExperiment(user, 'cta_color_experiment');
  const ctaColor = experiment.get('cta_color', 'blue');

  // LaunchDarkly
  const ctaColor = client.stringVariation('cta-color-experiment', context, 'blue');
  ```

  ```js title="Single parameter, JavaScript" lines wrap theme={null}
  //Statsig
  const experiment = statsig.getExperiment('cta_color_experiment');
  const ctaColor = experiment.get('cta_color', 'blue');

  // LaunchDarkly
  const ctaColor = client.variation('cta-color-experiment', 'blue') as string;
  ```
</CodeGroup>

#### Option 2: JSON flag for multiple parameters

Use a JSON flag when your experiment controls multiple parameters at once. Each variation is a JSON object containing all the parameters for that arm.

For example, the variations for a checkout experiment might be:

* Control: `{ "cta_text": "Buy Now", "cta_color": "blue" }`
* Treatment: `{ "cta_text": "Get Started", "cta_color": "green" }`

Here's how:

<CodeGroup>
  ```ts title="Multiple parameters, Node.js (server-side)" expandable lines wrap theme={null}
  // Statsig
  const experiment = Statsig.getExperiment(user, 'checkout_flow_experiment');
  const ctaText = experiment.get('cta_text', 'Buy Now');
  const ctaColor = experiment.get('cta_color', 'blue');

  interface CheckoutConfig {
    cta_text: string;
    cta_color: string;
  }

  // LaunchDarkly
  const defaults: CheckoutConfig = { cta_text: 'Buy Now', cta_color: 'blue' };

  const config = client.jsonVariation(
    'checkout-flow-experiment',
    context,
    defaults
  ) as CheckoutConfig;

  const { cta_text: ctaText, cta_color: ctaColor } = config;
  ```

  ```ts title="Multiple parameters, JavaScript" lines wrap theme={null}
  //Statsig
  const experiment = statsig.getExperiment('checkout_flow_experiment');
  const ctaText = experiment.get('cta_text', 'Buy Now');
  const ctaColor = experiment.get('cta_color', 'blue');

  // LaunchDarkly
  const defaults: CheckoutConfig = { cta_text: 'Buy Now', cta_color: 'blue' };

  const config = client.jsonVariation('checkout-flow-experiment', defaults) as CheckoutConfig;
  const { cta_text: ctaText, cta_color: ctaColor } = config;
  ```
</CodeGroup>

## Step 3: Migrate Statsig metrics to LaunchDarkly metrics

LaunchDarkly supports both LaunchDarkly hosted metrics and warehouse native metrics:

* **LaunchDarkly hosted metrics**: You create LaunchDarkly hosted metrics from metric events that you instrument in your application code.
* **Warehouse native metrics**: If you are using [BigQuery](/docs/home/warehouse-native/bigquery), [ClickHouse](/docs/home/warehouse-native/clickhouse), [Databricks](/docs/home/warehouse-native/databricks), [Redshift](/docs/home/warehouse-native/redshift), or [Snowflake](/docs/home/warehouse-native/snowflake) to store metric events, you can export experiment data to your warehouse where you can conduct custom, advanced analysis in addition to LaunchDarkly’s existing experiment analysis. To learn how to set up warehouse native metrics, read [Warehouse native metrics](/docs/home/warehouse-native/metrics).

The following sections describe the process for migrating Statsig metrics to LaunchDarkly hosted metrics.

Statsig creates metrics from `logEvent()` calls. LaunchDarkly creates hosted metrics from metric events that you instrument in your app using `track()` calls in LaunchDarkly SDKs. Each event uses a unique event key, which is the same string you pass as the first argument to `track()`. To learn more, read [Tracking custom events](/docs/sdk/features/events).

### Tracking metric events

Statsig uses `logEvent()` to record metric events. LaunchDarkly hosted metrics use `track()`. Both associate the event with the user or context that triggered it.

Here is a comparison of the two methods:

<CodeGroup>
  ```ts title="Node.js (server-side)" lines wrap theme={null}
  //Statsig
  Statsig.logEvent(user, 'purchase_completed', purchaseAmount, {
    product_id: 'prod-123',
    category: 'electronics',
  });

  // LaunchDarkly
  client.track('purchase-completed', {
      product_id: 'prod-123',
      category: 'electronics'
    },
    purchaseAmount);
  ```

  ```js title="JavaScript" lines wrap theme={null}
  //Statsig
  statsig.logEvent('button_click', 'checkout', { page: 'cart' });

  //LaunchDarkly
  client.track('button-click', context);
  ```
</CodeGroup>

<Note>
  **Metric values and metadata**

  In the Node.js (server-side) SDK, `track()` uses the signature `track(key, context, data?, metricValue?)`. Pass Statsig's numeric `value` as `metricValue` (the fourth argument). Use `undefined` for `data` when you are not attaching a JSON payload to the event. LaunchDarkly does not support arbitrary metadata on individual `track()` calls the way Statsig's fourth `metadata` argument does. If you need to segment results by a property such as `product_id`, include that attribute on the `LDContext` you pass to `track()` instead.
</Note>

### Creating metrics in LaunchDarkly

Here is the basic procedure for recreating LaunchDarkly hosted metrics:

1. In LaunchDarkly, navigate to **Metrics** and click **Create metric**.
2. Set **Event key** to the same string you use as the first argument to `client.track()`. For example, a Statsig metric on the `purchase_completed` event can map to a LaunchDarkly metric whose event key is `purchase-completed`.
3. Select the metric type:
   * **Page viewed** for page views
   * **Clicked or tapped** for clicks
   * Custom **Count** or **Occurrence (Percent)** for events where occurrence matters, for example, `button_click`
   * Custom **Sum** or **Average** for events where the value matters, for example, `purchase_completed` with a revenue amount
4. Configure the metric's success direction (higher or lower is better).

For full instructions on how to create metrics, read [Creating metrics](/docs/home/metrics/create-metrics). To learn how to create warehouse native metrics instead, read [Warehouse native metrics](/docs/home/warehouse-native/metrics).

<Frame caption="The metric creation dialog.">
  <img src="https://mintcdn.com/launchdarkly/A4UXoRTW8ATNw4yq/images/auto/metric-examples-5.auto.png?fit=max&auto=format&n=A4UXoRTW8ATNw4yq&q=85&s=f5b876f756099cf182ef7bc7246d1a38" alt="The metric creation dialog." width="1276" height="1010" data-path="images/auto/metric-examples-5.auto.png" />
</Frame>

Read the sections below for details on how to translate specific Statsig metric types and fields into LaunchDarkly hosted metrics when you create them.

#### Metric type mapping

This table explains how Statsig metric types map to LaunchDarkly hosted metric fields. The first column lists the Statsig metric type, and the accompanying row lists the equivalent LaunchDarkly metric field values.

The `ratio`, `funnel`, `composite`, `composite sum`, and `percentile` Statsig metric types have no direct LaunchDarkly equivalent. You can use a percentile analysis method with custom count and custom numeric metrics.

Refer to this table when you are recreating your metrics in LaunchDarkly:

<table>
  <thead>
    <tr>
      <th scope="col">Statsig metric type</th>
      <th scope="col">LaunchDarkly <code>kind</code></th>
      <th scope="col">LaunchDarkly <code>isNumeric</code></th>
      <th scope="col">LaunchDarkly <code>unitAggregationType</code></th>
      <th scope="col">LaunchDarkly <code>analysisType</code></th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>event\_count\_custom</code></td>
      <td><code>custom</code></td>
      <td><code>false</code></td>
      <td><code>sum</code></td>
      <td><code>mean</code></td>
    </tr>

    <tr>
      <td><code>sum</code></td>
      <td><code>custom</code></td>
      <td><code>true</code></td>
      <td><code>sum</code></td>
      <td><code>mean</code></td>
    </tr>

    <tr>
      <td><code>mean</code></td>
      <td><code>custom</code></td>
      <td><code>true</code></td>
      <td><code>average</code></td>
      <td><code>mean</code></td>
    </tr>

    <tr>
      <td><code>event\_user</code></td>
      <td><code>custom</code></td>
      <td><code>false</code></td>
      <td><code>average</code></td>
      <td><code>mean</code></td>
    </tr>

    <tr>
      <td><code>event\_user\_window</code></td>
      <td><code>custom</code></td>
      <td><code>false</code></td>
      <td><code>average</code></td>
      <td><code>mean</code></td>
    </tr>

    <tr>
      <td><code>percentile</code> (as a metric type)</td>
      <td>custom</td>
      <td><code>true</code> or <code>false</code></td>
      <td><code>sum</code> or <code>average</code></td>
      <td><code>P99</code>, <code>P95</code>, <code>P90</code>, <code>P75</code> or <code>P50</code></td>
    </tr>

    <tr>
      <td><code>ratio</code></td>
      <td>n/a</td>
      <td>n/a</td>
      <td>n/a</td>
      <td>n/a</td>
    </tr>

    <tr>
      <td><code>funnel</code></td>
      <td>n/a</td>
      <td>n/a</td>
      <td>n/a</td>
      <td>n/a</td>
    </tr>

    <tr>
      <td><code>composite</code>/<code>composite sum</code></td>
      <td>n/a</td>
      <td>n/a</td>
      <td>n/a</td>
      <td>n/a</td>
    </tr>
  </tbody>
</table>

#### Metric field mapping

The following table lists Statsig metric definition fields and their equivalent fields in LaunchDarkly:

<table>
  <thead>
    <tr>
      <th scope="col">Statsig field</th>
      <th scope="col">LaunchDarkly field</th>
      <th scope="col">Notes</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>name</code></td>
      <td><code>name</code></td>

      <td />
    </tr>

    <tr>
      <td><code>id (name::type)</code></td>
      <td><code>key</code></td>
      <td>LaunchDarkly metric keys must be all lowercase. Replace any non-alphanumeric characters with hyphens.</td>
    </tr>

    <tr>
      <td><code>description</code></td>
      <td><code>description</code></td>

      <td />
    </tr>

    <tr>
      <td>
        <code>directionality</code> = <code>"increase"</code>
      </td>

      <td>
        <code>successCriteria</code> = <code>"HigherThanBaseline"</code>
      </td>

      <td />
    </tr>

    <tr>
      <td>
        <code>directionality</code> = <code>"decrease"</code>
      </td>

      <td>
        <code>successCriteria</code> = <code>"LowerThanBaseline"</code>
      </td>

      <td />
    </tr>

    <tr>
      <td><code>metricEvents\[0].name</code></td>
      <td><code>eventKey</code></td>
      <td>Copy the exact event name used in SDK <code>track()</code> calls</td>
    </tr>

    <tr>
      <td>
        <code>unitTypes</code> containing <code>"userID"</code>
      </td>

      <td>
        <code>randomizationUnits</code> containing <code>"user"</code>
      </td>

      <td />
    </tr>

    <tr>
      <td>Not available in Statsig</td>
      <td><code>unit</code></td>
      <td>Usually <code>user</code></td>
    </tr>
  </tbody>
</table>

## Step 4: Set up experiments in LaunchDarkly

After updating your SDK and importing your flags and metrics, you can create your experiment in the LaunchDarkly UI. The process differs from Statsig's because LaunchDarkly experiments are flag-based.

To set up an experiment in LaunchDarkly:

1. Create or choose a feature flag with variations representing your experiment arms. For a JSON experiment, each variation is a JSON object of parameters. For a simpler A/B test, each variation is a string or boolean value.
2. In the LaunchDarkly UI, navigate to **Experiments** and click **Create experiment**.
3. Select the flag you created as the experiment flag.
4. Choose the flag variation to use as the control.
5. Add one or more metrics for the events you want to measure in the experiment.
6. Set a traffic allocation and start the experiment.

That's it! You've migrated your experiments from Statsig to LaunchDarkly.

To learn more, read [Creating experiments](/docs/home/experimentation/create).

## Next steps

That's just the beginning of everything you can do with LaunchDarkly. Here are some suggestions for further reading:

* [Creating metrics](/docs/home/metrics/create-metrics)
* [Creating flags](/docs/home/flags/create)
* [Creating experiments](/docs/home/experimentation/create)
* [Analyzing experiment results](/docs/home/experimentation/analyze)
* [Contexts](/docs/home/flags/contexts)
* [Migrating your existing feature flag solution to LaunchDarkly](/docs/guides/account/migrating-solutions)

Or, if you want to learn more about the SDKs we used as examples above:

* [LaunchDarkly Node.js (server-side) SDK reference](/docs/sdk/server-side/node-js)
* [LaunchDarkly JavaScript SDK reference](/docs/sdk/client-side/javascript)

If you have more questions or need further assistance, [start a Support ticket](https://support.launchdarkly.com/hc/en-us/requests/new).

<View title="Developer">
  <Note>
    **Want to know more? Start a trial.**

    Your 14-day trial begins as soon as you sign up. Get started in minutes using the in-app Quickstart. You'll discover how easy it is to release, monitor, and optimize your software.<br /><br />

    Want to try it out? <a href="https://app.launchdarkly.com/signup">Start a trial</a>.
  </Note>
</View>

<View title="Federal docs" />

<View title="EU docs" />
