October 24, 2026
A site's design tokens usually change by accident: a renamed CSS variable, a theme color edited in a CMS panel that skips code review, a dependency bump that quietly swaps a default. None of that trips a type checker or a unit test. This is the setup for catching it anyway, using enrichr-cli, a free command that reads a page's fonts, colors, type scale and CSS variables in a real browser and writes them as stable JSON.
Why the JSON output, not the report
The default output is a readable report meant for a terminal, and it is not meant to be diffed: it is formatted for a person, with column widths and summaries that can shift between runs even when nothing about the design changed. The JSON format is the one built for this:
npx enrichr-cli tokens example.com -f json -o tokens.json
The same sections come out in the same order every time, with names that describe rank or size
(--color-palette-3, --text-xl) rather than a guess at intent, so two runs against
an unchanged page produce byte-identical files. -o tokens.json writes straight to a file; leave
it off and the JSON prints to stdout instead.
Check the environment first
Before spending a job's time loading a page, confirm the runner can actually do it:
npx enrichr-cli doctor
It checks the Node version (the CLI needs 22 or newer) and whether a Chrome, Edge, Brave or Chromium
browser is on the machine, and exits non-zero only if Node is too old. No browser is a warning, not a
failure, because tokens, fonts and colors fall back to reading the
page's CSS without one; GitHub's ubuntu-latest runner ships Chromium already, so this step
usually just confirms there is nothing to fix.
A minimal GitHub Actions workflow
This runs on a schedule, reads one page, and fails if its design tokens differ from the committed baseline:
name: Design token check
on:
schedule:
- cron: "0 9 * * *" # once a day
workflow_dispatch: # and on demand
jobs:
check-tokens:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "22"
- run: npx enrichr-cli doctor
- name: Read today's tokens
run: npx enrichr-cli tokens https://example.com -f json -o tokens.json
- name: Compare against the committed baseline
run: git diff --exit-code --no-index baseline/tokens.json tokens.json
git diff --exit-code does the actual check: it prints the difference and exits with status 1
if the files differ, which fails the job. --no-index lets it diff two working-tree files that
are not both staged the same way. The first time you run this, copy tokens.json to
baseline/tokens.json and commit it; that commit is the point someone reviewed and approved.
Updating the baseline on purpose
When a design change is intentional — a rebrand, a new accent color, a type-scale change — the
check is supposed to fail once. Re-run the same command locally, overwrite
baseline/tokens.json with the new output, and commit it in the same pull request as the design
change. The next scheduled run passes again, and the commit history shows exactly when, and why, the
baseline moved.
When to diff fields instead of the whole file
A whole-file diff is the least code to write and the right place to start. It gets noisy only if a field
changes for reasons nobody cares about — a palette color moving from the third rank to the fourth
because its share of the page shifted by a fraction of a percent, say. If that happens, diff the specific
fields that matter instead of the whole file, with jq:
# only fail if the named color roles change, ignore ranked palette order
diff <(jq .colors.roles baseline/tokens.json) <(jq .colors.roles tokens.json)
Narrowing the check to colors.roles, fonts or customProperties
(whichever section you actually care about) keeps the signal without losing the rest of the baseline as a
reference.
What this does not catch
This reads computed styles: colors, fonts, the type scale, spacing, radii, shadows and CSS variables. It has no idea whether the page looks right, whether a layout broke, or whether an image failed to load. It is a design-token check, not a visual regression tool, and the two are worth running side by side rather than picking one. It also cannot see what ran before the page finished loading — GSAP tweens, compiled WebGL shaders, a Three.js scene — which is a documented gap in the CLI itself, not something specific to this CI setup.
Watching a reference site you do not control
The same workflow works against any public URL, including a design-system source of truth you depend on, a vendor's embeddable widget, or a competitor you are tracking. Keep the schedule modest — once a day is enough to notice a redesign, and it is polite to the site you are reading. For your own deployed site, running the same check right after a deploy step catches a regression before a user does, which is the more common reason teams add this in the first place.
For the full command reference, see the Enrichr CLI page. For what the local read cannot see and what the hosted alternative adds, see Enrichr vs designlang and extract-design-system.
FAQ
Can I check a website's design tokens automatically in CI?
Yes. Run npx enrichr-cli tokens example.com -f json -o tokens.json in a workflow step, then diff that file against a committed baseline with git diff --exit-code or a small script. Fail the job if they differ.
Does this need a paid service?
No. enrichr-cli is free, MIT-licensed and has no dependencies beyond Node 22+ and a Chromium-based browser, which GitHub's standard runners already have. There is no account and no API key for the tokens, fonts and colors commands.
What should I actually diff: the whole JSON file, or specific fields?
Start with the whole file through git diff --exit-code tokens.json; it is the least code to write. Move to a field-level diff (with jq or a short Node script) once you find fields that change for reasons you do not care about, such as a palette entry two ranks lower by a fraction of a percent of page coverage.
Will this catch a visual bug, like a broken layout?
No. It reads computed styles: colors, fonts, the type scale, spacing and CSS variables. It has no opinion on whether the page looks right. For that, pair it with a screenshot-diff tool, or see what Enrichr's hosted capture adds for motion and 3D below.
Why would my own site's design tokens change without someone meaning to?
A CSS variable gets renamed in one file and not another, a dependency update changes a default, or a CMS-driven theme color gets edited in a settings panel that does not go through code review. Checking the rendered tokens catches all three, because it reads what the browser actually computed, not the source file someone remembered to update.
Can I use this to watch a site I do not control, like a vendor or a reference design system?
Yes, the command works on any public URL. Running it against someone else's site in CI just means your pipeline, not theirs, so keep the schedule reasonable: once a day is plenty for noticing a redesign.