Skip to main content
AC
Quality & Security4.8 KBMIT licensed

design-system-drift

Original, written for TechTide client work

Measure design system decay in a frontend codebase with five quantified metrics: hardcoded colors, component reinvention, token adoption, context provider bloat, accessibility gap. Use when auditing UI consistency, sizing a refactor, or proving drift with numbers. Not for merging multiple audits into one roadmap: use cross-domain-audit-synthesis. Not for building new marketing pages: use awwwards-2026.

  • design
  • system
  • drift

SKILL.md

Design System Drift

Quantify how far a frontend has drifted from its design system. Five metrics, each with a command or formula and a threshold, so the audit ends in numbers, not adjectives.

Metric 1: Hardcoded color census

grep -rn '#[0-9a-fA-F]\{3,8\}' src/ --include='*.tsx' --include='*.css' | grep -v node_modules | wc -l
grep -roh '#[0-9a-fA-F]\{3,8\}' src/ --include='*.tsx' --include='*.css' | sort -u | wc -l

First number is total occurrences, second is unique colors. Under 50 = Healthy. 50-200 = Moderate. 200-500 = Significant. Over 500 = Failed.

Metric 2: Component reinvention ratio

Count custom implementations vs library usages per category: modals, buttons, dropdowns, tooltips, toasts, form inputs.

Formula: reinventions / (reinventions + library_usages) * 100.

Under 20% = Healthy. 20-50% = Mixed. 50-80% = Library ignored. Over 80% = Library decorative.

Metric 3: Token adoption rate

grep -rn 'var(--' src/ --include='*.tsx' --include='*.css' | wc -l   # token usage
grep -rn 'style={{' src/ --include='*.tsx' | wc -l                   # raw inline values

Formula: token_usages / (token_usages + raw_values) * 100.

Over 80% = Healthy. 50-80% = Moderate. Under 50% = Token system decorative.

Metric 4: Context provider bloat

grep -rn 'createContext\|React.createContext' src/ | wc -l
find src/ -name '*Context*' -o -name '*Provider*' | xargs wc -l | sort -rn | head -20

Under 10 contexts = Normal. 10-20 = Heavy. Over 20 = Context soup. Any single context file over 500 lines: decompose immediately.

Metric 5: Accessibility gap from reinvention

grep -rn 'aria-' src/components/ --include='*.tsx' | wc -l
grep -rn 'role=' src/components/ --include='*.tsx' | wc -l
grep -rn 'tabIndex\|onKeyDown' src/components/ --include='*.tsx' | wc -l

Every reinvented component without these attributes is debt the library would have handled for free. Read this metric together with Metric 2: high reinvention plus low aria counts is compounding a11y debt.

Output format

MetricCurrentTargetGapPriority
Hardcoded colorsN<50N-50HIGH if >200
Reinvention ratioN%<20%N-20%HIGH if >50%
Token adoptionN%>80%80-N%MEDIUM
Context countN<10N-10MEDIUM if >15
A11y coverageN attrsBaselineGapHIGH if reinvention >50%

Good vs bad

Bad conclusion: "The codebase has drifted quite a bit from the design system and could use cleanup."

Good conclusion: "312 hardcoded colors (41 unique), reinvention 64%, token adoption 38%. Verdict: library is decorative. Priority: consolidate colors to tokens (HIGH), replace the 6 custom modals (HIGH)."

Verification

Run all five metric commands from the repo root. Expect each to return a number, and the report table to contain no empty cells and no adjectives in place of values. If a grep returns 0 unexpectedly, check the source layout first (a src/ that is actually app/ or .jsx instead of .tsx) and adjust the globs before trusting the zero.

Spot-check Metric 2: open 3 files counted as reinventions. Expect each to actually reimplement a library component, not wrap it. Wrappers that delegate to the library count as library usage, reclassify them.

Completion checklist

  • [ ] All five metrics computed with commands or counts shown
  • [ ] Grep globs adjusted to the project's real file layout
  • [ ] Reinvention counts spot-checked against 3 real files
  • [ ] Output table complete with gap and priority per metric
  • [ ] Every HIGH priority tied to a threshold breach, not opinion

Any box unchecked: not done. Fix or say so.

Footguns

  • Counting wrappers as reinventions. Inflates Metric 2 and points the refactor at healthy code. Fix: a wrapper that renders the library component is a library usage.
  • Trusting zeros from wrong globs. A Vue or .jsx codebase greps clean on *.tsx and looks healthy. Fix: confirm file extensions and roots before running the census.
  • Reporting only totals for colors. 500 occurrences of 6 tokens-to-be is a different problem than 500 unique hexes. Fix: always report both counts.
  • Turning thresholds into goals mid-audit. Adjusting the threshold to make the number green defeats the audit. Fix: thresholds are fixed, report the breach.

More in Quality & Security

All skills