APIs break silently. A field gets renamed, a required parameter is added, an enum value is removed — and nothing stops it from shipping. Clients crash in production, mobile apps get stuck on the wrong version, and you're debugging a diff that should have been caught in review.
DriftGuard is an open-source tool that enforces API type safety across OpenAPI, GraphQL, and gRPC — detecting exactly what changed, whether it's breaking, and which parts of your codebase are affected.
The problem it solves
When a team ships an API change, the questions that actually matter are:
- Is this change breaking? Will existing clients stop working?
- What is affected? Which files or services call the changed endpoint?
- Did CI catch it? Or did it slip through code review?
Most tools answer one of these. DriftGuard answers all three — for all three major API schema formats.
How it works
Given two versions of a schema, DriftGuard classifies every change as breaking, non-breaking, or informational, then optionally scans your source code to surface the call sites that are affected.
drift-guard compare openapi --base old.yaml --head new.yaml
// response
BREAKING DELETE /users/{id}
BREAKING POST /orders — required field `payment_method` added
NON-BREAKING GET /products — description updated
The same command works for GraphQL:
drift-guard compare graphql --base old.graphql --head new.graphql
And for gRPC Protobuf:
drift-guard compare grpc --base old.proto --head new.proto
Impact analysis — which code calls what changed
The diff tells you what changed. Impact analysis tells you where it matters:
drift-guard impact --schema new.yaml --source ./src
// response
BREAKING DELETE /users/{id}
src/services/user.service.ts:42 deleteUser()
src/controllers/admin.controller.ts:18 removeAccount()
This scans your source files for references to changed endpoints and maps each breaking change to the exact file and line number. It works across OpenAPI, GraphQL, and gRPC.
Severity rules
Not every change is equally dangerous. DriftGuard uses a built-in ruleset to classify each type of change:
// **Change** **Severity**
Remove an endpoint / field / type Breaking
Add a required parameter Breaking
Change a field type Breaking
Rename an enum value Breaking
Add an optional field Non-breaking
Add a new endpoint Non-breaking
Update documentation Informational
The full ruleset covers all three schema types — OpenAPI, GraphQL, and gRPC severity rules are documented here.
CI integration — one step
The GitHub Action installs in a single step:
- uses: pgomes13/drift-guard-engine@v1
with:
format: github
fail-on-breaking: true
On every pull request, DriftGuard:
Detects your API framework (NestJS, Express, Fastify, Gin, Echo, etc.)
Generates the current schema from your running code
Diffs it against the base branch schema
Posts a structured comment to the PR
Fails the check if breaking changes are present
A PR with breaking changes looks like this in GitHub:
❌ 2 breaking changes detected
BREAKING POST /orders — required field `payment_method` added
BREAKING GET /users/{id}/profile — field `email` removed
The fail-on-breaking: true flag blocks the merge until the changes are either reverted or the PR author explicitly acknowledges them.
Multi-service / microservices
In a multi-service environment, you often need to notify consumer services when a provider API changes. DriftGuard has a broadcast pattern for this:
Provider workflow — runs on the service that owns the API:
- uses: pgomes13/drift-guard-engine@v1
with:
mode: upload-diff # stores the diff as an artifact
notify-consumers: true # triggers downstream checks
notify-token: ${{ secrets.NOTIFY_TOKEN }}
Consumer workflow — runs on services that call the provider:
on:
repository_dispatch:
types: [api-drift-detected]
- uses: pgomes13/drift-guard-engine@v1
with:
mode: impact-check # checks if this service is affected
source: ./src
When the provider ships a breaking change, DriftGuard opens a PR (or issue) in every consumer repo that references the changed endpoints — before anything reaches production.
Output formats
Four output formats are supported depending on where you're running:
**Format** **Use case**
text Terminal / local dev
json Machine-readable pipelines
markdown. Documentation, wikis
github GitHub PR comments
drift-guard compare openapi --base old.yaml --head new.yaml --format json
{
"breaking": [
{ "type": "endpoint_removed", "path": "DELETE /users/{id}", "severity": "breaking" }
],
"non_breaking": [],
"total": 1
}
SDK support — Go and Node.js
For programmatic use, DriftGuard ships as both a Go package and an npm package.
Go:
import "github.com/pgomes13/drift-guard-engine/pkg/compare"
result, err := compare.OpenAPI(oldSpec, newSpec)
for _, change := range result.Breaking {
fmt.Println(change.Path, change.Type)
}
Node.js / TypeScript:
import { compareOpenAPI } from "@pgomes13/drift-guard";
const result = await compareOpenAPI(oldSpec, newSpec);
result.breaking.forEach(c => console.log(c.path, c.type));
Both packages expose the same diff and impact analysis APIs with full TypeScript types.
Playground
There's an interactive playground where you can paste two schema versions side-by-side and see the diff and impact analysis live — no install required. Supports OpenAPI, GraphQL, and gRPC.
Installation
Homebrew
brew install pgomes13/tap/drift-guard
npm
npm install -g @pgomes13/drift-guard
Go
go install github.com/pgomes13/drift-guard-engine/cmd/drift-guard@latest
Why this matters
API changes are inevitable. The question is whether you find out about breaking changes before or after clients are affected. DriftGuard moves that signal into the PR — where it's cheap to fix — rather than production, where it isn't.
Full documentation, severity rules, and integration guides at: pgomes13.github.io/drift-guard-engine
Source: github.com/pgomes13/drift-guard-engine
Top comments (0)