npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@datadog/dd-flag-migration

v1.0.2

Published

CLI tool to migrate feature flags to Datadog

Downloads

1,041

Readme

Datadog Feature Flag Migration Tool

A CLI tool for migrating feature flags from your current provider into Datadog Feature Flags, with side-by-side evaluation to verify the migration before you switch over.

Supported providers: Eppo, LaunchDarkly


Prerequisites


Installation

Run without installing using npx:

# migrate flags
npx @datadog/dd-flag-migration migrate

# evaluate migrated flags
npx @datadog/dd-flag-migration evaluate

Contributing / running from source

See CONTRIBUTING.md.


Credentials you'll need

Credentials are read from environment variables. Set them in your shell (or .envrc, .env loader, secret manager, etc.) before running migrate or evaluate. If any required variable is missing, the tool prints a list of the missing names to stderr and exits with code 1.

Required for migrate

| Variable | Required when | Where to find it | |---|---|---| | DD_API_KEY | always | Datadog → Organization Settings → API Keys | | DD_APP_KEY | always | Datadog → Organization Settings → Application Keys | | EPPO_API_KEY | provider = Eppo | Eppo → Configuration → API Keys | | LAUNCHDARKLY_API_KEY | provider = LaunchDarkly | LaunchDarkly → Account settings → Authorization → Access tokens |

Your LaunchDarkly access token needs Reader role permissions (or a custom role with viewProject access) to read projects, environments, and flag configurations.

EPPO_* variables are checked only when you select Eppo as the source provider. LAUNCHDARKLY_* variables are checked only when you select LaunchDarkly. You don't need to set both.

Required for evaluate

Everything above, plus the SDK key for the source environment you're evaluating against and a Datadog client token:

| Variable | Required when | Where to find it | |---|---|---| | DD_CLIENT_TOKEN | always | Datadog → Organization Settings → Client Tokens | | EPPO_SDK_KEY | migration was from Eppo | Eppo → SDK Keys (server SDK key, one per environment) | | LAUNCHDARKLY_SDK_KEY | migration was from LaunchDarkly | LaunchDarkly → Account settings → Authorization → SDK keys (server-side, one per environment) |

SDK keys in both Eppo and LaunchDarkly are scoped to a single environment. Make sure the value you export matches the environment you intend to evaluate against — evaluate will surface a reminder if it sees mismatched results.

Datadog Application Key permissions

Your Datadog Application Key must have the following scopes enabled:

| Scope | Description | |---|---| | feature_flag_config_read | View Feature Flag Configurations | | feature_flag_config_write | Edit Feature Flag Configurations | | feature_flag_environment_config_read | Ability to view Feature Flag Environment settings | | feature_flag_environment_config_write | Ability to modify Feature Flag Environment settings | | restriction_policies_read | Read restriction policies (required for team-based access controls) | | restriction_policies_write | Write restriction policies (required for team-based access controls) | | teams_read | View Teams (required for team-based access controls) |

To set these permissions, go to Organization Settings → Application Keys, select your key, and enable the scopes listed above. The feature flag scopes are under the Feature Flags section; restriction_policies_read and restriction_policies_write are under Access Management; teams_read is under Teams.

Examples

Migrate from Eppo

export DD_API_KEY=...
export DD_APP_KEY=...
export EPPO_API_KEY=...

npx @datadog/dd-flag-migration migrate

Evaluate an Eppo migration

export DD_API_KEY=...
export DD_APP_KEY=...
export DD_CLIENT_TOKEN=...
export EPPO_SDK_KEY=...

npx @datadog/dd-flag-migration evaluate

Migrate from LaunchDarkly

export DD_API_KEY=...
export DD_APP_KEY=...
export LAUNCHDARKLY_API_KEY=...

npx @datadog/dd-flag-migration migrate

Evaluate a LaunchDarkly migration

export DD_API_KEY=...
export DD_APP_KEY=...
export DD_CLIENT_TOKEN=...
export LAUNCHDARKLY_SDK_KEY=...

npx @datadog/dd-flag-migration evaluate

Step 1 — Migrate flags

npx @datadog/dd-flag-migration migrate

The tool will walk you through:

  1. Select your provider — Eppo or LaunchDarkly
  2. Map environments — link each source environment (e.g. production) to the corresponding Datadog environment
  3. Select flags — choose which flags to migrate; flags already in Datadog are marked. Press Tab to toggle visibility of already-migrated flags, then Ctrl+A to select all remaining flags
  4. Confirm and migrate — flags are created in Datadog and enabled in the mapped environments. A progress bar tracks migration status in real time

API keys are read from environment variables (see Credentials). Pass --datadog-site=<site> to set the Datadog site without a prompt. For fully scripted runs, see Non-interactive mode below.

When the migration completes, a record is saved to ~/.dd-flag-migration/migration-<timestamp>.json. In interactive mode you'll be prompted to export results to an .xlsx file; in non-interactive mode pass --export=true to generate one.

Large migrations

For large flag sets, the tool supports splitting work across multiple runs:

  • Progress bar — a sticky progress bar shows how many flags have been migrated so far, updating in real time
  • Tab to filter — during flag selection, press Tab to hide flags that have already been migrated. Combined with Ctrl+A, this makes it easy to select only the remaining flags for the next run
  • Ctrl+C to save progress — pressing Ctrl+C during migration saves a partial migration file (~/.dd-flag-migration/migration-<timestamp>.json) with all flags that completed successfully before the interruption. You can resume later by filtering out already-migrated flags with Tab

LaunchDarkly-specific workflow

When migrating from LaunchDarkly, the tool adds these steps:

  1. Select a LaunchDarkly project — flags in LaunchDarkly are scoped to a project, so you pick one project at a time
  2. Select LaunchDarkly environments — choose which environments within that project to migrate
  3. Link environments — map each selected LaunchDarkly environment to a Datadog environment
  4. Select flags — flags already in Datadog are shown with a checkmark and will have their targeting synced for new environments rather than being re-created

The tool translates LaunchDarkly targeting rules, individual user targets, percentage rollouts, and fallthrough variations into equivalent Datadog targeting filters. Flags that use unsupported operators (segmentMatch, before, after) are automatically skipped with an explanation. Flags with prerequisites are migrated with a warning, since Datadog does not enforce prerequisites.

SDK key considerations

LaunchDarkly SDK keys are project-scoped — each project has its own set of SDK keys per environment. If you are migrating multiple LaunchDarkly projects that share the same flag keys, the flags will collide within a single Datadog organization.

For larger migrations with multiple projects, a good practice is to create Datadog sub-organizations so that each project's flags live in an independent org. Sub-organizations have their own API keys, environments, and flag namespaces, which avoids key conflicts entirely.

To create and manage sub-organizations, see Multi-Organization Accounts. When using sub-organizations, generate separate Datadog API and Application keys for each sub-org and run the migration tool once per org.

Non-interactive mode

Pass --interactive=false to run the migration entirely from CLI arguments, with no prompts. This is useful for scripted or CI environments.

Non-interactive migrations write a JSON result document to stdout. Status messages, progress output, and export messages are written to stderr so stdout can be piped into tools such as jq.

Required flags

| Flag | Description | |---|---| | --provider <Eppo\|LaunchDarkly> | Source provider (case-insensitive) | | --datadog-site <site> | Datadog site (e.g. datadoghq.com) | | --env-map <source,target> | Map a source environment to a Datadog environment. Repeat for each environment | | --feature-flag <key> | Flag key to migrate. Repeat for each flag. For LaunchDarkly, use <source-key>,<datadog-key> to rename the Datadog flag | | --project <key> | LaunchDarkly project key (LaunchDarkly only) |

Optional flags

| Flag | Description | |---|---| | --dry-run | Preview changes without writing to Datadog | | --export=<bool> | Export results to an .xlsx file after migration (default: false) |

Examples

Migrate two LaunchDarkly flags across two environments:

npx @datadog/dd-flag-migration migrate --interactive=false \
  --provider LaunchDarkly \
  --project my-ld-project \
  --datadog-site datadoghq.com \
  --env-map Production,Production \
  --env-map Staging,QA \
  --feature-flag flag-one \
  --feature-flag flag-two

Rename a LaunchDarkly flag while migrating it:

npx @datadog/dd-flag-migration migrate --interactive=false \
  --provider LaunchDarkly \
  --project my-ld-project \
  --datadog-site datadoghq.com \
  --env-map Production,Production \
  --feature-flag my-flag-1,my-renamed-flag-1

Migrate Eppo flags (no project key required):

npx @datadog/dd-flag-migration migrate --interactive=false \
  --provider Eppo \
  --datadog-site datadoghq.com \
  --env-map production,Production \
  --feature-flag my-flag

Dry run

To preview what would be created without making any changes:

npx @datadog/dd-flag-migration migrate --dry-run

This writes the full list of API requests that would be sent to a dry-run-<timestamp>.json file in the current directory.


Step 2 — Evaluate the migration

Once flags have been migrated, run the evaluation to compare how flags are evaluated in Eppo vs. Datadog for the same inputs:

npx @datadog/dd-flag-migration evaluate

The tool will:

  1. Select a migration file — pick from previous migrations (most recent first)
  2. Select a Datadog environment — choose which environment to evaluate against
  3. Enter a test subject ID — a user ID (or any string) to use for flag evaluation
  4. Run evaluations — the tool generates test cases from each flag's targeting rules and compares the provider and Datadog results side by side

Datadog and provider credentials are read from environment variables (see Credentials).

Results are displayed in a table showing the Eppo value, Datadog value, migration status, and whether the flag is enabled. Matching values are shown in green; differences in yellow.

You can optionally export the full results to an .xlsx file.

Flags

| Flag | Description | |---|---| | --use-latest-migration | Skip the migration file selector and use the most recent | | --test-subject-id=<id> | Set the subject ID non-interactively | | --flag-environment=<name> | Set the Datadog environment name non-interactively | | --datadog-site=<site> | Set the Datadog site non-interactively |

Example for scripted use:

npx @datadog/dd-flag-migration evaluate \
  --use-latest-migration \
  --test-subject-id=user-123 \
  --flag-environment=production \
  --datadog-site=datadoghq.com

Configuration

The only setting persisted to ~/.dd-flag-migration/config.json is your Datadog site (so you don't have to re-enter it on every run). Credentials are never read from or written to this file — set them as environment variables instead.

Non-US Datadog sites

If your Datadog organization is on a regional site (EU, US3, US5, etc.), pass the site for a single run:

npx @datadog/dd-flag-migration evaluate --datadog-site=datadoghq.eu

To save a default site for interactive runs, add the site to your config:

{
  "datadogSite": "datadoghq.eu"
}

| Site | datadogSite value | |---|---| | US1 (default) | datadoghq.com | | EU | datadoghq.eu | | US3 | us3.datadoghq.com | | US5 | us5.datadoghq.com | | AP1 | ap1.datadoghq.com |


How it works

Migration

Eppo

For each selected flag, the tool:

  • Reads the flag's variations, targeting filters, and targeting rules from Eppo
  • Creates an equivalent flag in Datadog via the Feature Flags API
  • Enables the flag in the Datadog environments that correspond to active Eppo environments

Flags of type BANDIT or LAYER are skipped (not yet supported).

LaunchDarkly

For each selected flag, the tool:

  • Reads the flag's variations, targeting rules, individual targets, and rollout configuration from LaunchDarkly
  • Maps the flag type (boolean or multivariate) to the corresponding Datadog value type (BOOLEAN, STRING, NUMERIC, or JSON)
  • Converts individual user targets into targeting filters with ONE_OF conditions on the key attribute
  • Translates each targeting rule's clauses into Datadog targeting rule conditions, mapping operators like in, contains, startsWith, endsWith, matches, and semver comparisons to their Datadog equivalents
  • Converts percentage rollouts from LaunchDarkly's 100,000-weight scale to Datadog's 0-100 scale
  • Creates a fallthrough (default) targeting filter for the environment
  • For flags that already exist in Datadog, syncs targeting for newly mapped environments instead of re-creating the flag
  • Enables the flag in Datadog environments where it was enabled (on: true) in LaunchDarkly

Archived flags and flags using unsupported operators (segmentMatch, before, after) are skipped automatically.

Evaluation

The evaluation tool generates test cases automatically from each flag's targeting rules — producing inputs that should match each rule and inputs that should not. It then calls the source provider's SDK and the Datadog feature flag CDN with the same subject ID and attributes, and compares the results.

This lets you verify that flag targeting logic was translated correctly before you cut over your application.