Brand Validate
nib brand validate runs 11 automated checks against your token files and component contracts — catching broken references, naming violations, WCAG failures, and structural issues before they reach production.
Before and After
Before validate: You rename a color token in your brand guidelines, run nib brand build, and ship. Two weeks later a PR breaks because a component contract references the old token name — caught in code review by chance.
After validate: nib brand validate catches the broken reference immediately. It also flags the camelCase segment in the token path you added last sprint, and warns that your button component contract is missing a disabled state token.
Quick Start
# Run all 11 checks
nib brand validate
# Fail only on schema errors (skip a11y and naming)
nib brand validate --fail-on schema
# Validate a specific tokens directory
nib brand validate --tokens-dir ./custom/tokensWhat It Checks
| Check | ID | What it catches |
|---|---|---|
| DTCG schema | V-01 | Tokens missing $type or $value |
| Required categories | V-02 | Missing color, typography, spacing, borderRadius, elevation |
| Semantic tokens | V-03 | Missing required aliases (color.interactive.default, color.background.*, etc.) |
| Naming conventions | V-04 | camelCase, spaces, or underscores in token path segments |
| Typography scale | V-05 | Missing required font-size steps (xs, sm, base, lg, xl, 2xl) |
| Contrast (a11y) | V-06 | Text/background pairs that fail WCAG AA (4.5:1 minimum) |
| Composite types | V-07 | Shadow, typography, or transition tokens with wrong value shapes |
| Deprecated tokens | V-08 | Tokens marked $extensions.nib.deprecated still referenced |
| Component contracts | V-09 | Contracts referencing token paths that don't exist |
| Extensions schema | V-10 | $extensions.nib fields with unknown or invalid keys |
| Circular references | V-11 | {token.path} references that form cycles |
Reading the Output
✓ nib brand validate
Checks run: 11
Tokens: 247
PASS V-01 DTCG schema compliance
PASS V-02 Required categories present
FAIL V-03 Required semantic tokens
PASS V-04 Naming conventions
WARN V-05 Typography scale completeness
FAIL V-06 Contrast (WCAG AA)
PASS V-07 Composite type shapes
PASS V-08 Deprecated token references
FAIL V-09 Component contract token references
PASS V-10 Extensions schema
PASS V-11 Circular references
Issues (4 errors, 1 warning):
ERROR V-03 color.text.default — required semantic token missing
ERROR V-06 color.text.muted on color.background.primary — contrast 3.2:1 (need ≥ 4.5:1)
ERROR V-09 Button.contract.json → tokens.root.default.background: "color.interactive.base" — not found
ERROR V-09 Badge.contract.json → tokens.root.default.text: "color.text.onBrand" — not found
WARN V-05 font-size.2xl missing (expected xs, sm, base, lg, xl, 2xl)Exit code is 1 when any errors are present (warnings don't fail the process).
Fixing Common Issues
V-03: Missing semantic tokens
nib looks for tokens at specific paths. If you've renamed tokens in your guidelines and regenerated, the semantic layer may not have re-mapped correctly.
# Regenerate from scratch
nib brand build
# Or check your semantic token file directly
cat docs/design/system/tokens/color-semantic.tokens.json | grep "interactive"V-04: Naming conventions
Token path segments must be lowercase with hyphens only. No camelCase, no underscores, no spaces.
// ✗ wrong
{ "brandColor": { "$type": "color", "$value": "#0066ff" } }
{ "brand_color": { "$type": "color", "$value": "#0066ff" } }
// ✓ correct
{ "brand-color": { "$type": "color", "$value": "#0066ff" } }V-06: Contrast failures
nib auto-fixes most contrast issues during nib brand build by adjusting the semantic layer. If you're getting V-06 after a build, you likely have a custom token with a manually specified value.
Check the exact pair in the error message and adjust the lighter or darker token until the ratio reaches 4.5:1.
Online contrast checker
Use Polypane contrast checker to find a passing value quickly.
V-09: Component contract references
A component contract references a token that doesn't exist in your token files. This happens when:
- A token was renamed during a brand refresh
- A contract was written before the token existed
# List all available token paths
nib brand build --dry-run
# Regenerate the contract from scratch (if it was auto-generated by nib)
nib component init Button --overwriteCI Integration
Add validate to your CI pipeline to catch regressions before merge:
# .github/workflows/design-system.yml
- name: Validate brand tokens
run: |
nib brand build
nib brand validateFail-on levels
nib brand validate --fail-on schema # only V-01 (strictest gating)
nib brand validate --fail-on required # V-01, V-02, V-03
nib brand validate --fail-on a11y # adds V-06 contrast checks
nib brand validate --fail-on all # all 11 checks (default)Pre-commit Hook
Catch issues locally before they hit CI:
# .husky/pre-commit (or equivalent)
nib brand validate --fail-on schemaConfiguration
brand.config.json controls which checks run by default:
{
"validate": {
"failOn": "all",
"skipChecks": ["V-11"],
"contrastLevel": "AA"
}
}| Field | Default | Options |
|---|---|---|
failOn | "all" | "schema", "required", "a11y", "components", "all" |
skipChecks | [] | Any check ID (V-01 through V-11) |
contrastLevel | "AA" | "AA" (4.5:1), "AAA" (7:1) |
Related Commands
nib brand build— Regenerate tokens from brand guidelinesnib brand audit— WCAG contrast audit report with remediation suggestionsnib component init— Create a component contract