LaunchDarkly Node.js SDK → OpenFeature

Every LaunchDarkly SDK call in your codebase.
Ranked by risk.

FlagLint is a free, open-source CLI that audits direct LaunchDarkly SDK usage, ranks migration risk, and generates OpenFeature rewrites only where safety can be proven.

FlagLint knows when not to rewrite.

MIT licensed · Node.js 20+ · Runs locally · No API key · No source upload
flaglint v0.7.0
$ npx flaglint audit ./src --cost-estimate
  Auditing ./src...

✓ Audit complete: 13 flags — 3 high risk, 10 medium risk

  Readiness: 50/100 · moderate
  10 safely automatable · 10 require manual review

Flag Key               Risk     Usages  Reason
────────────────────────────────────────────────────
<dynamic key>          High        8   dynamic key
checkout-experiment    High        1   detail evaluation
*                      High        1   bulk call
checkout-v2            Medium      1   safely automatable
payment-provider       Medium      1   safely automatable

  Estimate: 22.8h – 43.9h  (--cost-estimate)

→ next: flaglint migrate ./src --dry-run
Migration risk

Naive find-and-replace can silently
change production behavior.

LaunchDarkly is (key, context, fallback). OpenFeature is (key, fallback, context). A naive rewrite silently swaps context and fallback — and your flags evaluate against the wrong value. FlagLint rewrites only when the client, key, type, fallback, context, and destination binding can all be proven.

See the complete safe migration workflow →

Before LaunchDarkly SDK
checkout.ts
import * as ld from 'launchdarkly-node-server-sdk'
const client = ld.init(sdkKey)

const enabled = await client.boolVariation(
  'checkout-v2',
  ctx,          // ← context  (arg 2)
  false         // ← fallback (arg 3)
)

Vendor-locked. Argument order: key → context → fallback.

After FlagLint OpenFeature SDK
checkout.ts
import {OpenFeature} from '@openfeature/server-sdk'
const client = OpenFeature.getClient()

const enabled = await client.getBooleanValue(
  'checkout-v2',
  false,        // ← fallback (arg 2) ✓
  ctx           // ← context  (arg 3) ✓
)
LaunchDarkly remains your provider. FlagLint migrates the call-site API only — not your flag configuration or backend.
How it works

Audit, migrate, enforce.

Three commands. Each step is independent and reviewable — nothing is changed without your explicit action.

1

Audit

Get a risk-ranked overview of every LaunchDarkly call in your codebase before touching any code.

npx flaglint audit ./src npx flaglint audit ./src --format html

Need structured inventory? Use flaglint scan.

2

Migrate

Preview every safe rewrite as a reviewable diff. Then apply only the proven ones. Dynamic keys, detail evaluations, and bulk calls are always skipped.

npx flaglint migrate ./src --dry-run npx flaglint migrate ./src --apply
3

Enforce

Block new direct LaunchDarkly calls in pull requests. Emits SARIF for GitHub Code Scanning line annotations.

npx flaglint validate ./src \ --no-direct-launchdarkly
Proof and boundaries

Rewrites safe calls.
Stops at uncertainty.

Dry-run output separates safe rewrites from manual review.

One safe rewrite, one explicit skip.

Proven static calls are rewritten. Dynamic expressions stay visible for review.

- return ldClient.boolVariation("checkout-v2", ctx, false);
+ return flags.getBooleanValue("checkout-v2", false, ctx);
Skipped: dynamic flag key cannot be resolved statically.
Example result: 10 safe rewrites 3 manual-review cases 0 files changed

Know what it does, and what it does not do.

FlagLint is intentionally narrow: local analysis, guarded rewrites, and CI enforcement for LaunchDarkly Node.js server SDK usage.

  • Runs locally in your checkout.
  • No LaunchDarkly API key or SDK credentials required.
  • No source upload to a FlagLint service.
  • Unsafe cases are never silently rewritten.

Supported now

  • Node.js server SDK
  • JavaScript and TypeScript
  • Static typed evaluations
  • SARIF CI policy output

Manual review or outside coverage

  • Dynamic keys
  • Detail and bulk evaluations
  • Browser and React SDKs
  • Other languages and providers

Audit your codebase before changing it.

Start with the local audit, then use the docs when you are ready to inspect, migrate, or enforce the boundary in CI.