How Orphaned Tokens Detection Works in DESIGN.md: Finding Unused Color Tokens

Orphaned tokens detection is a linter rule that scans DESIGN.md specifications to identify color tokens defined in the system but never referenced by any component, flagging them as warnings to maintain design system hygiene.

The design.md repository provides a CLI toolchain for managing design system specifications. Its orphaned tokens detection capability analyzes component references to surface unused color definitions that inflate bundle sizes and complicate maintenance workflows.

How Orphaned Tokens Detection Works

The algorithm, implemented in packages/cli/src/linter/linter/rules/orphaned-tokens.ts, performs a multi-pass analysis to distinguish between actively used tokens and dead code.

Collecting Referenced Token Paths

First, the rule iterates over every component in the DesignSystemState. For each property value that references a token, it walks the global symbolTable to resolve the exact path (e.g., colors.primary) and stores these paths in a referencedPaths set. This captures direct token usage across all components.

Determining MD3 Family References

Material Design 3 (MD3) organizes colors into semantic families such as primary, on-primary, and primary-container. When any token from a family is referenced, the entire family is considered "in-use". The rule extracts family names using the colorFamily() helper, which strips known MD3 prefixes and suffixes, and stores active families in referencedFamilies.

Ignoring Baseline MD3 Families

A hard-coded constant MD3_STANDARD_FAMILIES enumerates baseline families (primary, secondary, tertiary, error, surface, background, outline) that are always shipped with the design system. Tokens belonging to these families are never reported as orphaned, even if unreferenced, ensuring core Material Design tokens remain available.

Identifying Truly Orphaned Tokens

For every color token defined in state.colors, the rule applies four filters:

  • Skip if the exact path exists in referencedPaths (direct use)
  • Skip if the token's family appears in referencedFamilies (semantic sibling usage)
  • Skip if the family is a baseline MD3 family
  • Otherwise, create a RuleFinding warning

The resulting warnings contain the token path and a message such as 'brand-blue' is defined but never referenced by any component.

Why Warn About Unused Color Tokens?

Design System Hygiene

Unreferenced tokens increase the surface area of a design system without delivering value. They often represent leftovers from experiments or copy-paste errors that clutter the specification.

Bundle Size and Performance

In generated code—whether CSS variables or theme objects—every token translates to data shipped to the client. Removing unused tokens directly trims bundle size and improves load performance.

Preventing Accidental Regressions

Warnings surface early in CI pipelines, ensuring tokens aren't silently removed from the spec while still being used indirectly in runtime code. The warning severity allows builds to continue while alerting developers to audit potential issues.

Running the Orphaned Tokens Linter

CLI Usage

Run the lint command to validate a DESIGN.md file and see orphaned token warnings:

design-md lint path/to/DESIGN.md --format=text

The command executes the full linter suite, including the orphaned-tokens rule, and prints findings to stdout. The implementation resides in packages/cli/src/commands/lint.ts.

Programmatic Integration

Import the rule directly to analyze design system state programmatically:

import { orphanedTokens } from './packages/cli/src/linter/linter/rules/orphaned-tokens.js';
import { buildState } from './packages/cli/src/linter/linter/rules/test-helpers.js';

const state = buildState({
  colors: {
    primary: '#ff0000',
    unused: '#00ff00',          // Not referenced
  },
  components: {
    button: { backgroundColor: '{colors.primary}' },
  },
});

const warnings = orphanedTokens(state);
console.log(warnings);
// → [{ path: 'colors.unused', message: '`unused` is defined but never referenced …' }]

CI Integration

Configure your CI pipeline to surface warnings without failing builds:


# .github/workflows/lint.yml

- name: Run DESIGN.md linter
  run: design-md lint . --format=json > lint-report.json
- name: Fail on errors, but show warnings
  run: |
    jq -e '.summary.errors > 0' lint-report.json && exit 1
    echo "✅ Lint passed; review any warnings (e.g., orphaned tokens)."

Summary

  • Orphaned tokens detection scans DesignSystemState to find unused color definitions in DESIGN.md files
  • The algorithm tracks direct token references and MD3 family usage while excluding baseline Material Design families
  • Warnings maintain design system hygiene by identifying dead code that increases bundle size
  • The rule operates at warning severity, allowing CI builds to continue while surfacing cleanup opportunities
  • Implementation resides in packages/cli/src/linter/linter/rules/orphaned-tokens.ts with CLI entry at packages/cli/src/commands/lint.ts

Frequently Asked Questions

What is the difference between an orphaned token and an unused variable?

An orphaned token is specifically a color token defined in the design system specification that no component references, whereas unused variables might refer to any design property. The orphaned-tokens rule specifically targets color definitions in state.colors and checks against component token references.

Why does the linter ignore baseline MD3 families even if they are unused?

Baseline families like primary, surface, and error are defined in the MD3_STANDARD_FAMILIES constant because they represent core Material Design tokens that should always remain available for runtime theming or dynamic usage, even if not statically referenced in the current component set.

Can I configure the severity of orphaned token warnings?

According to the source code in orphaned-tokens.ts lines 102-106, the rule's severity is hard-coded to warning. To change the behavior, you would need to modify the rule descriptor or filter findings in your CI pipeline, as the repository does not currently expose severity configuration for this specific rule.

How does the linter handle indirect token references?

The rule only detects explicit token references found by walking the symbolTable during component analysis. Indirect runtime usage—such as dynamic theme switching or JavaScript-generated class names—cannot be statically analyzed, which is why the warning severity allows builds to continue while prompting manual review.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →