<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Santosh Gupta</title>
    <description>The latest articles on DEV Community by Santosh Gupta (@santosh327).</description>
    <link>https://dev.to/santosh327</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1355884%2Ffc665efc-121c-4e94-922b-b82c8c63d7c2.jpg</url>
      <title>DEV Community: Santosh Gupta</title>
      <link>https://dev.to/santosh327</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/santosh327"/>
    <language>en</language>
    <item>
      <title>7 Things I Wish migrate-mongo Had After a Few Production Incidents</title>
      <dc:creator>Santosh Gupta</dc:creator>
      <pubDate>Mon, 10 Aug 2026 06:11:28 +0000</pubDate>
      <link>https://dev.to/santosh327/7-things-i-wish-migrate-mongo-had-after-a-few-production-incidents-4g2b</link>
      <guid>https://dev.to/santosh327/7-things-i-wish-migrate-mongo-had-after-a-few-production-incidents-4g2b</guid>
      <description>&lt;p&gt;I've used &lt;code&gt;migrate-mongo&lt;/code&gt; for years.&lt;/p&gt;

&lt;p&gt;It's simple, reliable, and honestly a good choice for many projects.&lt;/p&gt;

&lt;p&gt;But as our application grew, I started running into the same problems repeatedly: rollbacks, concurrent deployments, migration drift, and debugging what actually happened months ago.&lt;/p&gt;

&lt;p&gt;Eventually, I stopped working around those problems and built &lt;code&gt;mongo-migrate-kit&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here are the seven things I wanted.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Roll back a specific migration
&lt;/h2&gt;

&lt;p&gt;This was the one that frustrated me the most.&lt;/p&gt;

&lt;p&gt;Imagine three migrations went out:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;migration A  ✓
migration B  ✗
migration C  ✓
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I only want to undo B.&lt;/p&gt;

&lt;p&gt;With &lt;code&gt;migrate-mongo&lt;/code&gt;, rollback is based on the latest migration. There's no simple way to say "undo this particular migration."&lt;/p&gt;

&lt;p&gt;So you either roll back more than you want or start doing things manually.&lt;/p&gt;

&lt;p&gt;I've done the latter in production. Not fun.&lt;/p&gt;

&lt;p&gt;With &lt;code&gt;mongo-migrate-kit&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mmk down 20260101-the-broken-one.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or if you actually want to roll back a batch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mmk down &lt;span class="nt"&gt;--batch&lt;/span&gt; 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  2. Dry run before touching production
&lt;/h2&gt;

&lt;p&gt;Before running migrations in production, I want to know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which migrations are pending?&lt;/li&gt;
&lt;li&gt;What order will they run in?&lt;/li&gt;
&lt;li&gt;What is about to happen?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's why &lt;code&gt;mmk&lt;/code&gt; has dry-run support:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mmk dry-run up
mmk dry-run down
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It shows the plan without changing the database.&lt;/p&gt;

&lt;p&gt;I run this before production migrations now. It's a small thing, but it removes a lot of uncertainty.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Two deployments shouldn't run migrations simultaneously
&lt;/h2&gt;

&lt;p&gt;We once had two deployments trigger migrations almost at the same time.&lt;/p&gt;

&lt;p&gt;Both processes thought they were in charge.&lt;/p&gt;

&lt;p&gt;That's not a situation you want with database migrations.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mongo-migrate-kit&lt;/code&gt; uses a database-backed atomic lock:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Deploy A → acquire lock → run migrations → release

Deploy B → lock exists → stop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The lock has a TTL, so a crashed process doesn't leave the database permanently locked.&lt;/p&gt;

&lt;p&gt;And if you don't need locking locally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mmk up &lt;span class="nt"&gt;--no-lock&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  4. Know when an old migration was modified
&lt;/h2&gt;

&lt;p&gt;This one is easy to overlook.&lt;/p&gt;

&lt;p&gt;A migration runs in production.&lt;/p&gt;

&lt;p&gt;Someone later edits the file.&lt;/p&gt;

&lt;p&gt;The filename is still the same, so the migration history says everything is fine.&lt;/p&gt;

&lt;p&gt;But the code that exists in Git is no longer the code that ran in production.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mongo-migrate-kit&lt;/code&gt; stores a SHA-256 checksum for every migration.&lt;/p&gt;

&lt;p&gt;If the file changes, you can see the drift.&lt;/p&gt;

&lt;p&gt;And with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mmk up &lt;span class="nt"&gt;--strict&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the migration can fail instead of silently continuing.&lt;/p&gt;

&lt;p&gt;If the change was intentional:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mmk up 20260101-add-index.js &lt;span class="nt"&gt;--force&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Migration files are history. I think they should be treated that way.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Redo shouldn't require two commands
&lt;/h2&gt;

&lt;p&gt;During development, my migration loop was basically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;migrate down
migrate up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Over and over.&lt;/p&gt;

&lt;p&gt;So I added:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mmk redo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mmk redo 20260101-add-index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Small feature.&lt;/p&gt;

&lt;p&gt;Probably the command I use most while writing migrations.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Rollbacks shouldn't erase history
&lt;/h2&gt;

&lt;p&gt;A rollback is still an event.&lt;/p&gt;

&lt;p&gt;If a migration ran on Monday and was reverted on Tuesday, I want that information to remain in the database.&lt;/p&gt;

&lt;p&gt;Instead of deleting the migration record, &lt;code&gt;mmk&lt;/code&gt; marks it as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;applied → reverted
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The history keeps information such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;batch
status
appliedAt
revertedAt
duration
checksum
environment
executedBy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Months later, you can still answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Did this migration actually run in production?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's important when debugging old incidents.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. TypeScript shouldn't need a separate setup
&lt;/h2&gt;

&lt;p&gt;If your application is TypeScript, migration files should be TypeScript too.&lt;/p&gt;

&lt;p&gt;With &lt;code&gt;mongo-migrate-kit&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;MigrationContext&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mongo-migrate-kit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;up&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;MigrationContext&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;createIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;unique&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;down&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;MigrationContext&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;dropIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;email_1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No extra &lt;code&gt;ts-node&lt;/code&gt; setup or build step.&lt;/p&gt;

&lt;p&gt;JavaScript works too, including ESM and CommonJS.&lt;/p&gt;




&lt;h2&gt;
  
  
  Should you switch from &lt;code&gt;migrate-mongo&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;Maybe not.&lt;/p&gt;

&lt;p&gt;If you have a small project and a handful of migrations, &lt;code&gt;migrate-mongo&lt;/code&gt; is probably perfectly fine.&lt;/p&gt;

&lt;p&gt;I used it for years.&lt;/p&gt;

&lt;p&gt;These problems only started becoming painful when we had more migrations, more developers, more environments, and CI/CD deployments running against production.&lt;/p&gt;

&lt;p&gt;That's when migration tooling stops being just:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Run these files in order."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It becomes infrastructure.&lt;/p&gt;

&lt;p&gt;And infrastructure needs things like locking, audit history, drift detection, and safe rollbacks.&lt;/p&gt;




&lt;h2&gt;
  
  
  Already using &lt;code&gt;migrate-mongo&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;You don't need to rewrite your existing migrations.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mongo-migrate-kit&lt;/code&gt; can import your existing history:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;mongo-migrate-kit mongodb

mmk import &lt;span class="nt"&gt;--dry-run&lt;/span&gt;
mmk import
mmk up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The old changelog isn't modified.&lt;/p&gt;

&lt;p&gt;That's the reason I built this tool.&lt;/p&gt;

&lt;p&gt;Not because &lt;code&gt;migrate-mongo&lt;/code&gt; is bad.&lt;/p&gt;

&lt;p&gt;Because after enough production incidents, I knew exactly which features I wanted in my migration workflow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/guptasantosh327/mongo-migrate-kit" rel="noopener noreferrer"&gt;mongo-migrate-kit&lt;/a&gt;&lt;/strong&gt; is open source.&lt;/p&gt;

&lt;p&gt;If you've had a migration go wrong in production, I'd genuinely like to hear what happened. Those stories are usually where the best tooling ideas come from.&lt;/p&gt;

</description>
      <category>mongodb</category>
      <category>node</category>
      <category>database</category>
      <category>npm</category>
    </item>
    <item>
      <title>Moving from Migrate Mongo to Mongo Migrate Kit (mmk) Without Re Running Old Migrations</title>
      <dc:creator>Santosh Gupta</dc:creator>
      <pubDate>Thu, 25 Jun 2026 11:34:10 +0000</pubDate>
      <link>https://dev.to/santosh327/moving-from-migrate-mongo-to-mongo-migrate-kit-mmk-without-re-running-old-migrations-19j8</link>
      <guid>https://dev.to/santosh327/moving-from-migrate-mongo-to-mongo-migrate-kit-mmk-without-re-running-old-migrations-19j8</guid>
      <description>&lt;p&gt;If you're using &lt;strong&gt;migrate-mongo&lt;/strong&gt; and considering a switch, the biggest concern usually isn't features.&lt;/p&gt;

&lt;p&gt;It's this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Will I have to re-run old migrations or risk production data?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The short answer is no.&lt;/p&gt;

&lt;p&gt;I built &lt;strong&gt;mongo-migrate-kit&lt;/strong&gt; with migration adoption as a first class feature because switching migration tools shouldn't feel risky.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Most teams already have months or years of migration history.&lt;/p&gt;

&lt;p&gt;Re-running old migrations is dangerous.&lt;/p&gt;

&lt;p&gt;Editing migration records manually is even worse.&lt;/p&gt;

&lt;p&gt;What you really want is a way to tell the new tool:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"These migrations already ran. Start tracking them and leave everything else alone."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's exactly what &lt;code&gt;mongo-migrate-kit&lt;/code&gt; does.&lt;/p&gt;

&lt;h2&gt;
  
  
  Import Existing migrate-mongo History
&lt;/h2&gt;

&lt;p&gt;First, install the package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;mongo-migrate-kit mongodb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Preview the import:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx mmk import &lt;span class="nt"&gt;--dry-run&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This reads your existing &lt;code&gt;migrate-mongo&lt;/code&gt; changelog and shows what will be imported.&lt;/p&gt;

&lt;p&gt;Nothing is written to the database.&lt;/p&gt;

&lt;p&gt;Once you're happy with the output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx mmk import
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The migration history is copied into &lt;code&gt;mongo-migrate-kit&lt;/code&gt;'s tracking collection.&lt;/p&gt;

&lt;p&gt;Your original &lt;code&gt;migrate-mongo&lt;/code&gt; changelog remains untouched.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Happens Next?
&lt;/h2&gt;

&lt;p&gt;After importing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx mmk status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Previously applied migrations appear as applied.&lt;/p&gt;

&lt;p&gt;Any migration files that haven't run yet remain pending.&lt;/p&gt;

&lt;p&gt;When you run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx mmk up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Only pending migrations execute.&lt;/p&gt;

&lt;p&gt;Old migrations are never re-run.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I Built This
&lt;/h2&gt;

&lt;p&gt;I originally created &lt;code&gt;mongo-migrate-kit&lt;/code&gt; after running into rollback issues during a deployment.&lt;/p&gt;

&lt;p&gt;While using &lt;code&gt;migrate-mongo&lt;/code&gt;, I found myself wanting more control over migration safety and deployment workflows.&lt;/p&gt;

&lt;p&gt;That led to features such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rollback specific migrations or batches&lt;/li&gt;
&lt;li&gt;Dry-run support&lt;/li&gt;
&lt;li&gt;SHA-256 checksum validation&lt;/li&gt;
&lt;li&gt;Distributed migration locking&lt;/li&gt;
&lt;li&gt;Redo support&lt;/li&gt;
&lt;li&gt;TypeScript support&lt;/li&gt;
&lt;li&gt;Safe migration adoption from migrate-mongo&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Documentation
&lt;/h2&gt;

&lt;p&gt;Getting started takes only a few minutes:&lt;/p&gt;

&lt;p&gt;Deep dive on migration guide from migrate mongo:&lt;br&gt;
&lt;a href="https://mongo-migrate-kit.vercel.app/guide/migrate-mongo" rel="noopener noreferrer"&gt;https://mongo-migrate-kit.vercel.app/guide/migrate-mongo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;npm:&lt;br&gt;
&lt;a href="https://www.npmjs.com/package/mongo-migrate-kit" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/mongo-migrate-kit&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitHub:&lt;br&gt;
&lt;a href="https://github.com/guptasantosh327/mongo-migrate-kit" rel="noopener noreferrer"&gt;https://github.com/guptasantosh327/mongo-migrate-kit&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Migration tools should make deployments safer, not add anxiety.&lt;/p&gt;

&lt;p&gt;If you're looking for a &lt;strong&gt;migrate-mongo alternative&lt;/strong&gt; or need a &lt;strong&gt;MongoDB migration tool for Node.js&lt;/strong&gt; that can adopt existing migration history safely, give &lt;strong&gt;mongo-migrate-kit&lt;/strong&gt; a try.&lt;/p&gt;

</description>
      <category>database</category>
      <category>mongodb</category>
      <category>node</category>
      <category>npm</category>
    </item>
    <item>
      <title>I Built a MongoDB Migration Tool After One Bad Deploy</title>
      <dc:creator>Santosh Gupta</dc:creator>
      <pubDate>Sat, 06 Jun 2026 07:15:09 +0000</pubDate>
      <link>https://dev.to/santosh327/i-built-a-mongodb-migration-tool-after-one-bad-deploy-18j6</link>
      <guid>https://dev.to/santosh327/i-built-a-mongodb-migration-tool-after-one-bad-deploy-18j6</guid>
      <description>&lt;p&gt;A few months ago I shipped a bad MongoDB migration.&lt;/p&gt;

&lt;p&gt;Classic mistake.&lt;/p&gt;

&lt;p&gt;I had run 3 migrations.&lt;/p&gt;

&lt;p&gt;The third one had a bug.&lt;/p&gt;

&lt;p&gt;I only wanted to rollback &lt;strong&gt;that migration&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Turns out with &lt;code&gt;migrate-mongo&lt;/code&gt;, rollback is mostly:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;undo the last applied migration&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Which sounds fine until you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;multiple deployments&lt;/li&gt;
&lt;li&gt;multiple environments&lt;/li&gt;
&lt;li&gt;teammates deploying too&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;“Last applied” stops feeling obvious.&lt;/p&gt;

&lt;p&gt;I ended up manually undoing DB changes and fixing migration history myself.&lt;/p&gt;

&lt;p&gt;Not fun.&lt;/p&gt;

&lt;p&gt;That was the moment I realized our migration setup had started breaking down as the project grew.&lt;/p&gt;

&lt;h2&gt;
  
  
  The stuff I kept wishing existed
&lt;/h2&gt;

&lt;p&gt;After that incident I wrote down all the things I wanted from a migration tool:&lt;/p&gt;

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

&lt;p&gt;None of these felt unusual.&lt;/p&gt;

&lt;p&gt;They felt like things you eventually want once your project stops being small.&lt;/p&gt;

&lt;p&gt;So I ended up building one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Meet &lt;code&gt;mongo-migrate-kit&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;CLI name: &lt;code&gt;mmk&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;A few examples:&lt;/p&gt;

&lt;p&gt;Run pending migrations:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mmk up&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Rollback a specific migration:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mmk down migration-name&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Preview before touching production:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mmk up --dry-run&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Redo during development:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mmk redo&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  The hard problem: switching tools safely
&lt;/h2&gt;

&lt;p&gt;This was the part I cared about most.&lt;/p&gt;

&lt;p&gt;Migration tools are easy to adopt on day 1.&lt;/p&gt;

&lt;p&gt;They’re painful to switch after 50+ migrations already exist.&lt;/p&gt;

&lt;p&gt;I didn’t want people to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;rerun old migrations&lt;/li&gt;
&lt;li&gt;recreate indexes&lt;/li&gt;
&lt;li&gt;duplicate seed data&lt;/li&gt;
&lt;li&gt;accidentally touch production data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So I added:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mmk import&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;It reads your existing &lt;code&gt;migrate-mongo&lt;/code&gt; changelog and adopts the migration history.&lt;/p&gt;

&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mmk up&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;only runs new migrations.&lt;/p&gt;

&lt;p&gt;No replaying old history.&lt;/p&gt;

&lt;p&gt;No scary production moments.&lt;/p&gt;

&lt;h2&gt;
  
  
  One thing I intentionally don't support
&lt;/h2&gt;

&lt;p&gt;Imported &lt;code&gt;migrate-mongo&lt;/code&gt; migrations are forward-only.&lt;/p&gt;

&lt;p&gt;You can’t rollback imported migrations using &lt;code&gt;mmk&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I could have tried to force compatibility, but I didn’t trust it enough to be safe.&lt;/p&gt;

&lt;p&gt;Different execution models + database tooling = not something I wanted to gamble with.&lt;/p&gt;

&lt;p&gt;So the tool fails loudly instead of pretending everything is reversible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Curious what other teams are doing
&lt;/h2&gt;

&lt;p&gt;If you're running MongoDB migrations in production:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What’s your current setup?&lt;/li&gt;
&lt;li&gt;Have you hit similar pain points?&lt;/li&gt;
&lt;li&gt;Are you still happy with &lt;code&gt;migrate-mongo&lt;/code&gt;?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Would genuinely love feedback.&lt;/p&gt;

&lt;p&gt;Project:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mongo-migrate-kit&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Docs/demo:&lt;br&gt;
&lt;a href="https://mongo-migrate-kit.vercel.app" rel="noopener noreferrer"&gt;mongo-migrate-kit.vercel.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;npm:&lt;br&gt;
&lt;a href="https://www.npmjs.com/package/mongo-migrate-kit" rel="noopener noreferrer"&gt;mongo-migrate-kit&lt;/a&gt;&lt;/p&gt;

</description>
      <category>mongodb</category>
      <category>node</category>
      <category>backend</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
