# How to Detect Orphaned Color Tokens That Are Never Referenced in DESIGN.md

> Quickly find and remove unused color tokens referenced in DESIGN.md. Run the design-md lint command or import the orphanedTokens rule for automatic detection, ensuring cleaner code.

- Repository: [Google Labs Code/design.md](https://github.com/google-labs-code/design.md)
- Tags: how-to-guide
- Published: 2026-07-01

---

**Run `design-md lint` against your DESIGN.md file to automatically identify color tokens defined in YAML front-matter that no component references, or import the `orphanedTokens` rule from [`packages/cli/src/linter/linter/rules/orphaned-tokens.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/linter/rules/orphaned-tokens.ts) for programmatic detection.**

DESIGN.md files in the **google-labs-code/design.md** repository centralize visual design tokens in YAML front-matter blocks, with color values defined under the `colors:` key and later referenced by components using token paths like `{colors.primary}`. When you detect orphaned color tokens—defined values that remain unreferenced—you eliminate maintenance overhead and prevent visual inconsistencies in your design system. The repository ships with a dedicated linter that flags these unused tokens through the `orphanedTokens` rule.

## How the Orphaned Token Detection Algorithm Works

The detection logic lives in [`packages/cli/src/linter/linter/rules/orphaned-tokens.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/linter/rules/orphaned-tokens.ts) and processes the `DesignSystemState` object to distinguish between actively used and abandoned color definitions. The algorithm executes in four distinct phases to ensure accurate identification while respecting Material Design 3 system contracts.

### Collect Referenced Token Paths

The linter iterates over every component in `state.components` and examines each property value that constitutes a token reference. For every reference found, it looks up the corresponding key in the global `state.symbolTable` and records the matching path (e.g., `colors.primary`) in a `referencedPaths` set, as implemented in lines 63-71 of the rule file. This collection phase ensures the linter knows exactly which tokens are actively consumed by the design system.

### Derive Referenced Color Families

Material Design 3 tokens organize colors into families such as `primary`, `secondary`, and `tertiary`. The helper function `colorFamily(name)` normalizes token names by stripping MD3 prefixes (`on-`, `inverse-`) and suffixes (`-container*`, `-fixed*`, `-dim`, `-bright`, `-tint`, `-variant`), collapsing variants like `on-primary` or `primary-container` into the base family `primary`. This normalization logic appears in lines 26-38 and allows the linter to recognize when any member of a color family is in use.

### Exclude Standard MD3 Families

The `MD3_STANDARD_FAMILIES` set contains the core Material Design 3 color families that constitute the design system contract. Any token belonging to one of these standard families is automatically excluded from orphan detection, even if your specific design never references that particular token, as defined in lines 46-54. This prevents flagging system-level tokens that maintain compliance with the MD3 specification.

### Identify Truly Orphaned Tokens

For each color token defined in `state.colors`, the rule evaluates three strict conditions:

- The exact token path is absent from `referencedPaths`
- The token's family is absent from `referencedFamilies` (ensuring sibling tokens survive when any family member is used)
- The token's family is not listed in `MD3_STANDARD_FAMILIES`

Tokens satisfying all three criteria, as checked in lines 88-98, are emitted as findings with descriptive messages indicating they are defined but never referenced.

## Running the Linter via CLI

The `design-md lint` command registered in [`packages/cli/src/commands/lint.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/commands/lint.ts) (lines 15-22) automatically includes the orphaned-token rule in its `DEFAULT_RULES` set. Invoke the linter from your terminal to scan DESIGN.md files:

```bash

# Detect orphaned tokens with JSON output

design-md lint path/to/DESIGN.md --format json

```

The command returns findings in your chosen format, with each orphaned token report containing the token path and explanation:

```json
{
  "findings": [
    {
      "path": "colors.brand-blue",
      "message": "'brand-blue' is defined but never referenced by any component."
    }
  ],
  "summary": { "errors": 0, "warnings": 1, "infos": 0 }
}

```

## Programmatic Detection in Node.js

For integration into CI pipelines or custom tooling, import the rule directly and feed it a parsed `DesignSystemState`:

```typescript
import { parseDesignSystem } from '@design-md/parser';
import { orphanedTokens } from './packages/cli/src/linter/linter/rules/orphaned-tokens.js';

// Load DESIGN.md into state
const state = await parseDesignSystem('examples/totality-festival/DESIGN.md');

// Execute detection
const findings = orphanedTokens(state);

findings.forEach(f => {
  console.log(`${f.path}: ${f.message}`);
});

```

This approach mirrors the CLI behavior while allowing you to process findings programmatically or fail builds based on orphan counts.

## Summary

- **Orphaned color tokens** are YAML definitions in DESIGN.md files that no component references, creating maintenance debt and potential visual inconsistencies.
- The detection algorithm in [`packages/cli/src/linter/linter/rules/orphaned-tokens.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/linter/rules/orphaned-tokens.ts) cross-references `state.symbolTable` with `state.colors` to identify unused tokens.
- **Material Design 3 standard families** are automatically excluded from orphan detection to preserve system contract compliance.
- Use `design-md lint` for command-line detection or import `orphanedTokens` programmatically to integrate checks into build pipelines.
- The linter considers both exact token paths and color families, ensuring that related tokens (like `primary` variants) remain available when any family member is active.

## Frequently Asked Questions

### What are orphaned color tokens in DESIGN.md?

Orphaned color tokens are color values defined in the YAML front-matter of a DESIGN.md file (under the `colors:` key) that no component in the design system actually references through token paths like `{colors.tokenName}`. These unused definitions increase file size, create confusion during maintenance, and can lead to visual inconsistencies if accidentally applied in future iterations.

### How does the linter determine if a color token is orphaned?

The linter evaluates three conditions in [`packages/cli/src/linter/linter/rules/orphaned-tokens.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/linter/rules/orphaned-tokens.ts): the exact token path must not appear in `referencedPaths` (collected from all component properties), the token's family must not appear in `referencedFamilies` (determined via the `colorFamily()` helper), and the family must not be part of `MD3_STANDARD_FAMILIES`. Only tokens meeting all three criteria are flagged as orphaned.

### Why are standard Material Design 3 families excluded from orphan detection?

Standard MD3 families defined in `MD3_STANDARD_FAMILIES` represent the core color contract of the Material Design 3 system. These families (such as `primary`, `secondary`, and `tertiary`) are expected to exist in compliant design systems regardless of whether a specific implementation references every variant. Excluding them prevents the linter from flagging necessary system infrastructure as unused.

### Can I run the orphaned token check programmatically instead of using the CLI?

Yes, import the `orphanedTokens` function directly from [`packages/cli/src/linter/linter/rules/orphaned-tokens.ts`](https://github.com/google-labs-code/design.md/blob/main/packages/cli/src/linter/linter/rules/orphaned-tokens.ts) and pass it a `DesignSystemState` object obtained via `parseDesignSystem()`. This returns an array of findings that you can process in JavaScript or TypeScript applications, enabling integration into custom build tools, CI pipelines, or automated reporting systems without spawning CLI processes.