DEV Community

Cover image for DriftGuard: catching when your code quietly breaks your docs
Mahima Thacker
Mahima Thacker

Posted on

DriftGuard: catching when your code quietly breaks your docs

if you've ever shipped an SDK update and then, three weeks later, a GitHub issue lands saying "the README example doesn't work," you'll recognize this problem.
The code changed. The docs didn't. Users hit broken snippets. You only find out from the angry messages.

I built DriftGuard because I kept seeing this in Web3 SDKs - contracts get upgraded, the TypeScript SDK evolves, but the docs and example apps lag behind. By the time someone reports it, a dozen users have already been confused.

What it is

DriftGuard is a CLI + GitHub Action that detects "drift" - when changes in one layer of your project break another layer. It runs in CI on every pull request and posts inline annotations at the exact line that broke.

It's not a doc generator like Mintlify. It doesn't write docs for you. It just makes sure the docs you already have stay accurate.

contracts ─┐
SDK ─┼─▶ DriftGuard ─▶ ✓ no drift PR passes
docs ─┤ ✗ drift found PR fails with file:line
demos ─┘

Who it's for

DevRel engineers maintaining SDK docs and example apps
SDK maintainers who ship breaking changes occasionally
Web3 teams with contracts + SDK + docs + demo repos to keep in sync
If your project has a public API and docs that show how to use it, DriftGuard probably helps.

What it actually checks

Four layers, all deterministic — no AI guessing:

1) Solidity contracts: Function/event added or removed, mutability tightened, parameter type changes

2) TypeScript SDK: Exports added/removed, signature changes, kind changes (function → class)

3)Docs: TypeScript code blocks in .md/.mdx get re-type-checked against the current SDK

4) Demos Optional: runs install + test in real demo projects to catch runtime drift

When a check fails, you get a GitHub annotation right at the file:line in the PR diff. The same finding appears in the workflow summary as Markdown and in a SARIF report for GitHub's code-scanning tab.

How it works

Two steps:

1) Snapshot — run driftguard snapshot once. It captures your contracts, SDK exports, and doc snippets in a normalized JSON file. Commit it.

2) Check — on every PR, driftguard check recomputes the same shapes and diffs against the committed snapshot. Differences become findings.
The snapshot is the approval mechanism. If you intentionally change your SDK signature, you re-run driftguard snapshot to update the baseline. The next check passes.

For doc snippets, the validation step is the interesting part. Each TypeScript code block in your README gets compiled against your current SDK using a path-mapped ts-morph Project. If your SDK changes a signature, the snippet that calls the old shape stops compiling — and the check fails at the line of the snippet in the markdown file.

Quick start

npm install --save-dev @driftguardjs/cli
npx driftguard init # writes a starter config (auto-detects what's in your project)
npx driftguard snapshot # captures the baseline
git add .driftguard/snapshot.json driftguard.config.ts
git commit -m "add driftguard"

Add to your CI workflow:

- uses: mahimathacker/driftguard@v0
  with:
    mode: check
Enter fullscreen mode Exit fullscreen mode

That's the whole setup.

What I learned building it

Dogfooding catches bugs nothing else does. The first time I ran DriftGuard against its own repo, it produced 1500-character unreadable diffs — Zod schemas were expanding into huge inferred types. The code was correct. The output was unusable in a PR comment. No test would've caught this. I had to run the tool against itself to feel what a real user feels.

Bundling complex libraries doesn't always work. I spent two hours trying to bundle the GitHub Action into a single JavaScript file. Two libraries the tool uses (ts-morph and jiti) do runtime dynamic loading that no bundler can package cleanly. Eventually I gave up and made the action just install the CLI from npm at runtime. The simpler approach turned out to be the right one.

How AI shaped the workflow:

AI was fast at two specific things:

Architecture decisions before they became regrets — content-hash IDs for doc snippets (instead of line numbers, which break when you add a paragraph above), lenient-by-default snapshots (so users can adopt the tool without first fixing every broken example), syntactic types over inferred types in the diff output.

Diagnosing CI output — when a test PR didn't render annotations as expected, AI immediately pointed at "GitHub requires repo-relative paths, not absolute." That alone saved an hour of reading docs.
What AI didn't decide: when to stop polishing and ship. When to abandon the bundling path. What counts as a v0.1.0 blocker versus a v0.1.x polish item. Those judgment calls stayed with me.

Where to find it

npm: https://www.npmjs.com/package/@driftguardjs/cli
GitHub: https://github.com/mahimathacker/driftguard

Built as part of DevRel Uni Cohort 7. Next on the roadmap: Solidity snippet validation, AI-suggested fixes for broken snippets, and an MCP server so coding agents can query "what would break if I change X?" before they make the change.

If you try it on your own SDK, I'd love to hear what breaks first — issues or DMs both work.

Top comments (0)