Reach scores how much of your UI comes from your design system. Drift flags the components that bypass it, in pull requests and while your agent writes code.
Reach gives you one number for the repo. Drift gives you findings for the files you touch.
The score and where the leaks are.
Score: 68.4%The share of countable UI that comes from your design system.Other components 134Local components and other libraries.Styled host elements 56A div or span that carries a className or style.Leaks: 87Hardcoded hex colors and pixel values.Top offendersThe files where the leaks cluster.Five kinds of bypass, each with a severity.
import drift highA design system component imported from a local path instead of the package.local shadow highA component defined in the file under the same name as a design system export.token fingerprint mediumA component that hardcodes a design system hex token or class name.prop match mediumA local component whose props overlap a design system component's API.subcomponent mediumA local component that uses a design system's sub-components without the real parent.One score for design system adoption in React code, plus the hex colors and pixel values that bypass it. Comments on pull requests and generates a README badge.
v1.0.0 · 2026-07-07Flags components that bypass your design system: local copies, look-alikes and hardcoded tokens. Comments on the pull request with only the drift that PR introduces. Works with Carbon, MUI or an in-house design system.
v1.1.2 · 2026-07-07Component health across code, Figma and docs. Shows which components are solid in code but weak in design, and the other way round, in one HTML report.
In progressAsk an agent for a button and it often hand-rolls one instead of importing yours. Drift's Claude Code hook scans every file the agent writes and sends the findings back, so the agent fixes the drift in the same turn.
npx @usepolder/drift init --claudeWrites .polder.yml if it is missing, a PostToolUse hook in .claude/settings.json, and a managed section in CLAUDE.md.
One comment per pull request. It shows adoption, only the drift that PR introduced, and the commit that introduced it.
The same comment on Azure DevOps pull requests. Run polder-drift ci as a pipeline step. There is no extension to install.
Scan your working tree, a diff against a branch, or the whole repo. Add --json for scripts and agents.
You can make CI fail below a minimum score. How things are counted never changes, so scores stay comparable between teams.
@acme/ds/Button and <Table.Row>.div with a className or style.The engine is a Babel AST plus token fingerprints. When a finding is acceptable, silence it by ID, by rule or by path.
# .polderignore
a1b2c3d4e5f6 # one finding, by ID
rule:token-fingerprint # a whole rule
path:src/legacy/** # a path glob
Detection profiles for Carbon and MUI ship with Drift. Any other design system works through config, and npx @usepolder/drift profile can generate a profile from its source.
npx @usepolder/reach --library "@acme/ds"Score a React repo with Reach. Add --json for the full report.npx @usepolder/drift scan --allScan the whole repo with Drift. Without --all it scans your working-tree changes. Run your install step first so design system exports resolve.npx @usepolder/drift init --claudeSet up the Claude Code hook, so findings reach the agent as it writes.- uses: usepolder/reach@v1In a GitHub workflow: one pull request comment with the score and the change since the base branch.- uses: usepolder/drift@v1In a GitHub workflow: one pull request comment with the drift that PR introduces. Set fetch-depth: 0 on checkout.No. Reach and Drift run on your machine or in your CI, with no server and no account. Drift's engine needs no network and no LLM.
Reach reads React code (JSX and TSX). Drift reads TypeScript and JavaScript, ships with profiles for Carbon and MUI, and works with any other design system, including in-house ones, through config.
Drift does today, as a pipeline step. A Reach task for Azure DevOps and per-package scores for monorepos are on the roadmap.
No. You can set reach.fail_under to fail CI below a minimum score, which never changes the number.
Add its ID, a rule or a path glob to .polderignore. Suppressed findings do not fire the Claude Code hook either.
Nothing. Both tools are open source under Apache-2.0.
npx @usepolder/reach --library "@acme/ds"npx @usepolder/drift scan --all