Registry
Aalexbit-codemod avatar

feature-flag-stale-mining

Read-only mining for stale Backstage feature flags. Single JSSG step builds a repo-wide declare/consume index, then emits backstage_feature_flag_stale for declared-unused and consumed-undeclared names with confidence metadata.

alexbit-codemod3 executions

  • mining
  • metrics
  • backstage
  • feature-flags
  • stale
  • FeatureFlagsApi
  • tsx
  • typescript
Connect a repo
npx codemod feature-flag-stale-mining

feature-flag-stale-mining

Read-only miner for stale Backstage feature flags — names that are declared
but never consumed, or consumed but never declared (literal names only).

Companion to feature-flag-mining: that package inventories usage sites; this
one judges staleness via a repo-wide declare ↔ consume set-diff.

How it works

One JSSG step (scripts/codemod.ts) — required for Codemod Insights, which
binds widgets to a single workflow js_file:

  1. On the first file in a scan, build a repo-wide declare/consume index once
    (text-prefiltered disk walk + parse), then cache it in module memory and
    codemod:workflow state
  2. For each subsequent file, emit backstage_feature_flag_stale rows for stale
    sites in that file from the cached index (no re-walk)

Files whose source cannot match feature-flag signals are skipped before AST
detection. Source files are never modified (return null).

Stale kinds

stale_kindMeaning
declared_unusedDeclared (featureFlags / registerFlag) but never consumed
consumed_undeclaredGated (isActive / FeatureFlagged / $contains / schema) but never declared

Dynamic names (isActive(stepFeatureFlag), etc.) are ignored — they cannot be
set-diffed reliably from AST alone.

Metric: backstage_feature_flag_stale

fielddescription
stale_kinddeclared_unused or consumed_undeclared
confidencehigh for literal set-diff with empty other side
flag_nameLiteral flag id
fileRelative path of the stale site
line1-based line
symbolEnclosing function/class, or <file-scope>
usage_kindSite shape (declaration, is_active, feature_flagged, …)
declare_countHow many declare sites exist for this name (repo-wide)
consume_countHow many consume sites exist for this name
evidenceCompact proof string, e.g. declared_in_1_sites_consumed_in_0
remediationSuggested cleanup

What this does not report

  • Healthy flags (declared and consumed)
  • Framework FeatureFlagsApi plumbing (same denylist as usage miner)
  • Dynamic-only flag references
  • Whether users actually toggle a flag in the browser

License

MIT

Ready to evolve your codebase?

Build tailored, compiler-aware skills to assess, plan, and automate complex codebase changes.