Find the components that bypass your design system.

Drift flags local copies, look-alikes and hardcoded tokens, in pull requests and while your agent writes code.

View on GitHub
free and open sourcev1.1.2, released 2026-07-07
~/your-app
$ npx @usepolder/drift scan storefront.tsx ⚠ 4 drift signal(s) across 1 of 1 file(s) analysed. storefront.tsx import drift Card from './ui/Card' (imported locally instead of from the package) token fingerprint PriceSlider (#1976d2) prop match PriceSlider ~ MuiSlider (75%: value, onChange, min, max, step, disabled)

Five kinds of bypass, each with a severity.

The detection engine is a Babel AST plus token fingerprints. It is deterministic, needs no network and no model, and gives the same answer for the same code.

import drift high

A design system component imported from a local path instead of the package.

local shadow high

A component defined in the file under the same name as a design system export.

token fingerprint medium

A component that hardcodes a design system hex token or class name.

prop match medium

A local component whose props overlap a design system component's API.

subcomponent medium

A local component that uses a design system's sub-components without the real parent.

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 or edits 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. Set fetch-depth: 0 on checkout so Drift can tell new drift from old.

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. Exit code 1 on drift when fail_on_drift is on.

Works with any design system.

Config

Drift reads a .polder.yml at the repo root. Design system exports are resolved from node_modules, so run your install step first. Detection profiles for Carbon and MUI ship with Drift. For any other design system, npx @usepolder/drift profile can generate a profile from its source.

component_library: "@your-org/design-system"
allowlist: []
fail_on_drift: false

Silence what you accept

Suppress a finding by ID, a whole rule, or a path glob. Suppressed findings do not fire the Claude Code hook either.

# .polderignore
a1b2c3d4e5f6              # one finding, by ID
rule:token-fingerprint    # a whole rule
path:src/legacy/**        # a path glob

Run it on a repo.

npx @usepolder/drift scan --allScan the whole repo. Without --all it scans your working-tree changes. Run your install step first so design system exports resolve.
npx @usepolder/drift scan --diff origin/mainScan only what changed since a base branch.
- uses: usepolder/drift@v1In a GitHub workflow: one pull request comment with the drift that PR introduces.

Questions

What is design system drift?

Components that bypass your design system: local copies of design system components, same-name shadows, look-alikes with matching props, and hardcoded design tokens.

Does it send my code anywhere?

No. Drift runs on your machine or in your CI, with no server and no account. The engine needs no network and no LLM.

Which languages and design systems work?

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.

How does the Claude Code hook work?

npx @usepolder/drift init --claude installs a PostToolUse hook. Every file the agent writes or edits is scanned, and the findings go back to the agent, which fixes them in the same turn.

Does it run on Azure DevOps?

Yes. Run polder-drift ci as a pipeline step with fetchDepth: 0. There is no extension to install.

How do I silence a Drift finding I accept?

Add its ID, a rule or a path glob to .polderignore.

What does it cost?

Nothing. Drift is open source under Apache-2.0.

Part of Polder. See also Polder Reach. Latest release: v1.1.2, 2026-07-07.

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).