mongoose-drift
v1.3.0
Published
Schema versioning and diff tool for Mongoose
Maintainers
Readme
mongoose-drift
Track your Mongoose schema changes. Generate migrations. Keep your AI tools in the loop.
The problem
You add a field to a Mongoose model. You remove another one. Two weeks later you can't remember what changed, and there's no migration file. mongoose-drift fixes that.
Snapshot your schema, change your models, then diff the two to see exactly what's different — field by field, index by index. Generate a migration stub from the diff. And if you use an AI coding tool like Cursor, Claude Code, or Copilot, mongoose-drift automatically tells it about your schema on install.
How it works
flowchart LR
A["Your Mongoose\nmodel files"] -->|"snapshot --version 1.0.0"| B[("Snapshot saved\n.mongoose-drift/")]
B --> C["Edit your models\n(add fields, remove fields, etc.)"]
C -->|"diff 1.0.0 HEAD"| D["Diff output"]
D -->|"--stub"| E["migration.js\n(migrate-mongo)"]
D -->|"--json"| F["diff.json\n(machine-readable)"]
D -->|"--txt"| G["diff.txt\n(plain text)"]What is
HEAD? It means "my models right now, on disk" — no snapshot needed.diff 1.0.0 HEADcompares snapshot v1.0.0 against your current live model files.
Installation
npm install -D mongoose-driftAfter install, mongoose-drift automatically writes a context block into your AI agent files (
CLAUDE.md,.cursorrules,copilot-instructions.md, etc.) so your coding tools already know how to use it. See AI integration →
Quick start
Step 1 — Initialize
Point mongoose-drift at your models folder:
npx mongoose-drift init --models ./src/modelsThis saves a config to .mongoose-drift/default/config.json.
Step 2 — Take a snapshot
Freeze your current schema:
npx mongoose-drift snapshot --version 1.0.0Snapshot saved to .mongoose-drift/default/1.0.0.json. Commit this file — it's your schema history.
Step 3 — Edit your models
Go make changes. Add a field, remove one, change a type. Whatever you need.
Step 4 — See what changed
npx mongoose-drift diff 1.0.0 HEADOutput:
Schema diff: 1.0.0 → HEAD
Collection: User
+ phoneNumber (String) [FIELD ADDED]
- bio (String) [FIELD REMOVED]
~ role {"type":"String"} → {"type":"String","enum":["admin","user"]} [MODIFIED]
Summary: 0 added 0 removed 1 modifiedStep 5 — Generate a migration stub
npx mongoose-drift diff 1.0.0 HEAD --stubCreates migrations/default/1.0.0-to-HEAD.js:
// Auto-generated by mongoose-drift
module.exports = {
async up(db) {
// TODO: Add field 'phoneNumber'
// await db.collection('users').updateMany({}, { $set: { phoneNumber: null } });
// TODO: Remove field 'bio' — verify no data dependency first
// await db.collection('users').updateMany({}, { $unset: { bio: '' } });
// TODO: Field 'role' was modified — handle data transformation
},
async down(db) {
// TODO: Reverse the above operations
},
};Review it, uncomment the lines you want, and run with migrate-mongo.
AI integration
When you install mongoose-drift, it runs a postinstall script that writes a context block into every AI agent config file it finds in your project.
flowchart TD
A["npm install mongoose-drift"] --> B["postinstall script runs"]
B --> C["Writes context block into\nyour agent files"]
C --> D["CLAUDE.md"]
C --> E[".cursorrules\n.cursor/rules/mongoose-drift.mdc"]
C --> F[".github/copilot-instructions.md"]
C --> G[".windsurfrules"]
C --> H[".augment/guidelines.md"]
C --> I["gemini.md"]
D & E & F & G & H & I --> J["Your AI tool now knows\nwhich commands to run\nto read your schema"]The block tells your AI tool:
- that mongoose-drift is installed
- which commands to run to list snapshots, read schema, and diff changes
- where snapshot files live
After saving your first snapshot, refresh the AI files so agents can also see which versions exist:
npx mongoose-drift snapshot --version 1.0.0
npx mongoose-drift setup-aiSafe to re-run. The block is wrapped in <!-- mongoose-drift:start/end --> markers. Re-running setup-ai only replaces that block — everything else in your file is untouched.
What your AI can then do
Once the context is injected, you can ask your AI assistant:
"What fields does the User collection have?" "Did any fields change since v1.0.0?" "Write a migration for the changes since the last snapshot."
The agent will run npx mongoose-drift show <version> or diff <version> HEAD on its own to get the answer.
All commands
| Command | What it does |
|---------|-------------|
| init --models <path> | Set up config pointing to your models folder |
| snapshot --version <v> | Save a snapshot of your current schema |
| diff <from> <to> | Compare two snapshots (use HEAD for current state) |
| log | List all saved snapshots |
| show <version> | Print the full schema for a snapshot as JSON |
| setup-ai | Refresh AI agent instruction files |
Diff flags
| Flag | What it does |
|------|-------------|
| --stub | Generate a migrate-mongo migration file |
| --json | Output diff as JSON (useful for scripts or AI tools) |
| --txt [path] | Export diff as a plain-text file |
| -p, --project <name> | Use a specific project namespace (default: default) |
Multi-project / monorepo
If you have multiple services or databases, isolate them with -p:
npx mongoose-drift init --models ./apps/auth/models -p auth
npx mongoose-drift init --models ./apps/billing/models -p billing
npx mongoose-drift snapshot --version 1.0.0 -p auth
npx mongoose-drift diff 1.0.0 HEAD -p billing --stubEach project stores its snapshots and migrations separately under its own namespace.
Programmatic API
import {
extractSchemas,
diffSnapshots,
detectPotentialRenames,
} from 'mongoose-drift';
const before = await loadSnapshot('1.0.0', 'default');
const after = await loadSnapshot('HEAD', 'default');
const diff = diffSnapshots(before, after);
// Field changes for a collection
const fieldChanges = diff.collections['User']?.changes ?? [];
const renames = detectPotentialRenames(fieldChanges);
// Index changes for a collection
const indexChanges = diff.collections['User']?.indexChanges ?? [];Exported functions
| Function | Description |
|----------|-------------|
| extractSchemas(modelsPath) | Extract schemas from a models directory |
| diffSnapshots(before, after) | Compute field- and index-level diff |
| detectPotentialRenames(changes) | Find likely renames in field changes |
| saveSnapshot(options) | Save a snapshot to disk |
| loadSnapshot(version, project) | Load a snapshot from disk |
| listSnapshots(project) | List all saved snapshot versions |
| generateStub(diff, from, to, project) | Generate a migration stub file |
| setupAI(projectRoot) | Write or update AI agent instruction files |
Exported types
import type {
SchemaSnapshot,
DiffResult,
FieldChange,
IndexChange,
CollectionChange,
FieldDefinition,
} from 'mongoose-drift';Requirements
- Node.js >= 16
- Mongoose >= 6 (installed in your project — mongoose-drift reads your model files)
License
MIT
