DEV Community

Cover image for I Built a MongoDB Migration Tool After One Bad Deploy
Santosh Gupta
Santosh Gupta

Posted on

I Built a MongoDB Migration Tool After One Bad Deploy

A few months ago I shipped a bad MongoDB migration.

Classic mistake.

I had run 3 migrations.

The third one had a bug.

I only wanted to rollback that migration.

Turns out with migrate-mongo, rollback is mostly:

undo the last applied migration

Which sounds fine until you have:

  • multiple deployments
  • multiple environments
  • teammates deploying too

“Last applied” stops feeling obvious.

I ended up manually undoing DB changes and fixing migration history myself.

Not fun.

That was the moment I realized our migration setup had started breaking down as the project grew.

The stuff I kept wishing existed

After that incident I wrote down all the things I wanted from a migration tool:

  • run one migration file
  • rollback a specific migration
  • preview migrations before running (dry-run)
  • avoid concurrent deploys stepping on each other (locking)
  • detect edited migrations (checksums)
  • a redo command for local development
  • TypeScript support without setup pain
  • migration history that doesn’t disappear after rollback

None of these felt unusual.

They felt like things you eventually want once your project stops being small.

So I ended up building one.

Meet mongo-migrate-kit

CLI name: mmk

A few examples:

Run pending migrations:

mmk up

Rollback a specific migration:

mmk down migration-name

Preview before touching production:

mmk up --dry-run

Redo during development:

mmk redo

The hard problem: switching tools safely

This was the part I cared about most.

Migration tools are easy to adopt on day 1.

They’re painful to switch after 50+ migrations already exist.

I didn’t want people to:

  • rerun old migrations
  • recreate indexes
  • duplicate seed data
  • accidentally touch production data

So I added:

mmk import

It reads your existing migrate-mongo changelog and adopts the migration history.

Then:

mmk up

only runs new migrations.

No replaying old history.

No scary production moments.

One thing I intentionally don't support

Imported migrate-mongo migrations are forward-only.

You can’t rollback imported migrations using mmk.

I could have tried to force compatibility, but I didn’t trust it enough to be safe.

Different execution models + database tooling = not something I wanted to gamble with.

So the tool fails loudly instead of pretending everything is reversible.

Curious what other teams are doing

If you're running MongoDB migrations in production:

  • What’s your current setup?
  • Have you hit similar pain points?
  • Are you still happy with migrate-mongo?

Would genuinely love feedback.

Project:

mongo-migrate-kit

Docs/demo:
mongo-migrate-kit.vercel.app

npm:
mongo-migrate-kit

Top comments (4)

Collapse
 
exdevops profile image
EXDEV-ops •

Most people only see the finished product. Looking back, what was the biggest problem you didn’t expect when you first started building it?

Collapse
 
santosh327 profile image
Santosh Gupta •

Probably the migration import part. Running migrations is easy, but safely adopting existing migrate-mongo history without rerunning things or touching prod data was trickier than I expected.

I had to make sure the users can easily migrate it and never look back.

Collapse
 
jay_sardar_60b306a874ac93 profile image
Jay Sardar •

I understand that all operations in a transaction are committed or rolled back together, but what about the migration entry in the migrations collection? Is that also part of the transaction?

Collapse
 
santosh327 profile image
Santosh Gupta •

Yes.
The session in up/down is also used for writing migration history.

So with mongo-migrate-kit either both the migration and history update succeed together, or everything rolls back.

This end to end transaction support was something I felt missing in migrate-mongo. It’s optional and can be enabled in mmk.config.js / mmk.config.ts.