deslop/feature-flag

Disallow stale feature flags that permanently guard dead code.

  • Category: Dead Code
  • Severity: warn
  • Source: deslop-js
  • Framework: global
  • Enabled when: react-doctor deadCode analysis enabled (default true); whole-project scan only — skipped in --diff/--staged modes
  • Documentation: https://github.com/millionco/deslop-js

Validation prompt

Use this to decide whether a fired diagnostic is real or a false positive.

Fires when deslop's feature-flag detector records a FeatureFlag (kind env-var, sdk-call, or config-object) whose guardsDeadCode is true — meaning the flag's enclosing if/ternary guard span (guardLineStart..guardLineEnd) overlaps a line that is itself reported as an unusedExport: an env-var like process.env.FEATURE_X / FF_X / NEXT_PUBLIC_ENABLE_X, an SDK call such as boolVariation/useGate/checkGate/isEnabled/getTreatment/useFeatureFlagEnabled/flag (sdkProvider names the vendor: LaunchDarkly, Statsig, Unleash, GrowthBook, Split, PostHog, Vercel Flags), or a config-object access like config.features / settings.toggle. False positive to suppress: a flag still actively toggled for a live rollout, A/B experiment, or kill-switch where BOTH branches are reachable and serve real traffic — only permanently-settled flags (the detector's guardsDeadCode==true / unreachable guarded branch) are cleanup candidates, so suppress if the flag's value still varies in production or the disabled branch is intentionally kept warm.

Fix prompt

Use this once validation confirms the diagnostic is real.

Retire the settled flag and inline the surviving branch: confirm the flag is permanently on (or off) in every environment, then delete the if/ternary guard, the unused branch, the flag lookup (the process.env read, the SDK call like boolVariation('x') / useGate('x'), or the config.features.x access), plus the now-orphaned env entry, SDK registration, or config key — e.g. replace if (boolVariation('newCheckout')) renderNew(); else renderOld(); with just renderNew(); and drop renderOld. A flag guarding code the rest of the repo no longer imports is finished rolling out; leaving it forces every reader to reason about a dead branch. See https://github.com/millionco/deslop-js