Your design system has leaks. Polder finds them.

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.

View on GitHub
free and open sourceruns on your machine or in CI
~/your-app
$ npx @usepolder/reach --library "@acme/ds" Polder Reach Score: 68.4% (412 DS / 602 countable instances) DS components 412 Other components 134 Styled host elements 56 Leaks: 87 (61 hex colors, 26 px values) Top offenders: src/styles/legacy.css (34)

What you get back

Reach gives you one number for the repo. Drift gives you findings for the files you touch.

Reach

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.

Drift

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.

Three tools. Use one or all.

Catch drift while the code is written.

Ask 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.
A narrow ditch running through polder grassland

GitHub Action

One comment per pull request. It shows adoption, only the drift that PR introduced, and the commit that introduced it.

Azure DevOps

The same comment on Azure DevOps pull requests. Run polder-drift ci as a pipeline step. There is no extension to install.

CLI

Scan your working tree, a diff against a branch, or the whole repo. Add --json for scripts and agents.

The same code gives the same answer.

Reach has no settings on the formula

You can make CI fail below a minimum score. How things are counted never changes, so scores stay comparable between teams.

DS instances
DS + other components + styled host elements
Counts as yours. A capitalized JSX element that resolves to your library, including @acme/ds/Button and <Table.Row>.
Counts against you. Any other component, and any lowercase element like div with a className or style.

Drift needs no network and no model

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.

Try it

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.

Questions

Does it send my code anywhere?

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.

Which languages and design systems work?

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.

Does it run on Azure DevOps?

Drift does today, as a pipeline step. A Reach task for Azure DevOps and per-package scores for monorepos are on the roadmap.

Can I change how Reach calculates the score?

No. You can set reach.fail_under to fail CI below a minimum score, which never changes the number.

How do I silence a Drift finding I accept?

Add its ID, a rule or a path glob to .polderignore. Suppressed findings do not fire the Claude Code hook either.

What does it cost?

Nothing. Both tools are open source under Apache-2.0.

Find your leaks.

npx @usepolder/reach --library "@acme/ds"
npx @usepolder/drift scan --all
Photos via Wikimedia Commons, cropped and compressed: header De Biesbosch-polder by Paul van de Velde (CC BY 2.0); footer Foto uit de lucht Spijkenisse by Peter van der Sluijs (CC BY-SA 4.0).