The ultimate API sidekick for Frontend and Backend teams.
Frontend developers are constantly blocked waiting for incomplete backend endpoints. When the backend is finally ready, the real responses often drift from the original OpenAPI contract, silently breaking the UI.
Contract Drift Detection is a lightweight developer CLI that solves both problems. It gives you a fully stateful mock API while the backend is being built, and acts as a Drift-Detecting Proxy to catch contract violations once the real backend is ready.
Stop using static, hardcoded JSON mocks. CDD reads your OpenAPI 3.x spec and spins up a local API that actually remembers state.
- How it works: You send a
POST /users, and CDD saves it to a local.mock-db.jsonfile. Your nextGET /usersreturns that new user. All defined right inside your OpenAPI spec usingx-mock-statevendor extensions. No backend code required. - Validation default: Mock responses are schema-validated by default. Disable only when needed with
--no-validate-mock.
When the real backend is ready, don't change your frontend code. Just start CDD in Proxy Mode.
- How it works: CDD intercepts frontend requests, forwards them to the real backend, and validates the response payload against your OpenAPI spec. If the backend team changed
userIdtouser_id, CDD prints a massive red drift alert in your terminal before it breaks production.
Frontend developers usually have to choose between stateless OpenAPI mocks or stateful JSON mocks. CDD gives you both, plus real-time drift analysis.
| Feature | contract-drift-detection |
Stoplight Prism | json-server |
|---|---|---|---|
| OpenAPI 3.x Support | β Yes | β Yes | β No |
| Stateful Mocks (CRUD) | β
Yes (.mock-db.json) |
β No (Stateless) | β
Yes (db.json) |
| Custom Mock Logic | β
Yes (x-mock-state) |
β No | β No |
| Proxy & Drift Detection | β Yes (Console & CI Alerts) | β Yes (Validation Proxy) | β No |
Don't have an OpenAPI spec yet? Run this command to generate a starter contract and boot up the stateful server immediately:
npx contract-drift-detection@latest quickstartHere is how you actually integrate this into your React, Next.js, or Vue project workflow.
npm install -D contract-drift-detection concurrentlyAdd these scripts so your team can easily run the frontend and the mock server together.
{
"scripts": {
"dev": "next dev",
"mock:api": "cdd --spec ./openapi.yaml --port 4010",
"dev:mock": "concurrently \"npm run mock:api\" \"npm run dev\"",
"proxy:api": "cdd --spec ./openapi.yaml --drift-check http://localhost:8080 --port 4010",
"dev:proxy": "concurrently \"npm run proxy:api\" \"npm run dev\""
}
}Change your API base URL in your frontend .env file to point to CDD:
VITE_API_BASE_URL=http://localhost:4010Now, your workflow is simple:
- Backend isn't ready? Run
npm run dev:mock. - Backend is running locally on 8080? Run
npm run dev:proxyto start catching drift!
Don't let backend contract drifts get merged into main. You can use CDD in your CI pipeline to block Pull Requests if the backend responses diverge from the OpenAPI contract.
The workflow uses CI-friendly flags:
--fail-on-driftto exit non-zero on mismatches.--reporter json --report-file drift-report.jsonfor machine-readable artifacts.
(Check out our ready-to-use drift gate workflow example at .github/workflows/drift-check.yml in this repository).
Use this table for precise expectations in enterprise adoption:
| Capability | Status | Notes |
|---|---|---|
| OpenAPI 3.x contract loading | β Supported | Local files + remote/discovered specs |
| REST route generation (GET/POST/PUT/PATCH/DELETE) | β Supported | Core stateful CRUD coverage |
| JSON request/response validation | β Supported | Primary validation path |
Stateful behavior via x-mock-state |
β Supported | create, update, delete, replace, append |
| Proxy-based drift detection | β Supported | Includes --strict, ignore rules, reporters |
| XML / multipart / binary-heavy payload parity | Depends on endpoint shape and schema coverage | |
| Streaming/SSE/WebSocket contracts | β Not targeted | Focus is OpenAPI REST request/response |
| GraphQL / gRPC / SOAP-native protocols | β Not supported | Outside OpenAPI REST scope |
- Team rollout guide: see docs/PRODUCTION_ADOPTION.md
- CI drift gate template: docs/GITHUB_ACTIONS_TEMPLATE.md
- Weekly canary workflow: .github/workflows/reliability-canary.yml
To make your mocks stateful, add the x-mock-state extension directly under your path operations.
Supported actions: create, update, delete, replace, append.
Example:
paths:
/tickets/{id}/resolve:
post:
x-mock-state:
action: update
target: tickets
find_by: id
set:
status: resolvedTemplate values are supported in assign and set:
{{body.field}}{{params.id}}{{query.key}}{{headers.authorization}}
serve subcommand is optional. Root command accepts serve options directly.
cdd [--spec <path> | --spec-url <url> | --discover <backend-url>]
[--port 4010]
[--host 0.0.0.0]
[--db .mock-db.json]
[--cors-origin *]
[--drift-check <url>]
[--no-validate-mock]
[--fallback-to-mock]
[--verbose]
cdd init [--spec openapi.yaml] [--template rest-crud|none]
cdd quickstart [--spec openapi.yaml] [--port 4010]
--spec(Local file)--spec-url(Explicit remote URL)--discover(Auto-scans common backend paths)
If you don't have the spec locally, use --discover http://localhost:8080. CDD will automatically check common paths including:
/openapi.json/swagger.json/v3/api-docs- etc.
Default CORS is enabled for all origins (*) for fast local onboarding. For stricter browser setup:
npx contract-drift-detection@latest --spec ./openapi.yaml --cors-origin http://localhost:5173When the server is running, you can access:
GET /__healthβ health checkGET /__specβ resolved OpenAPI in memoryGET /__routesβ generated route summary
- Default behavior validates mock-mode responses against your OpenAPI success schemas.
- To disable this check temporarily, pass
--no-validate-mock. - Proxy drift detection (
--drift-check) remains available for validating real backend responses.
Create a .driftignore file in your project root to suppress specific drift findings.
Each line format:
[METHOD] [PATH_PATTERN] [JSON_PATH]
Examples:
* * body.trace_id
GET /users body.metadata.*
POST /orders/* body.items.*.debug
Notes:
*wildcard is supported in all three fields.JSON_PATHis matched as dot-path form rooted atbody(notdata).- Use
bodyto ignore root-level errors (for example AJV instance path/). - Use
body.*to ignore object-level item paths (for example AJV paths like/0,/1). - Lines starting with
#are comments.
You can verify .driftignore load status in startup logs:
Ignore rules: cli-paths=..., file-rules=<count>
- Could not discover an OpenAPI spec: Try an explicit endpoint with
--spec-url, or usequickstartif the backend doesn't expose OpenAPI yet. - EADDRINUSE: address already in use: Port 4010 is taken. Pass
--port 4020. - Debugging: Need full stack traces? Run
CDD_SHOW_STACK=1 npx contract-drift-detection@latest --spec ./openapi.yaml
MIT
contract-drift-detection, cdd