ts-migrate-mongoose
A migration framework for Mongoose, built with TypeScript.

Motivation
ts-migrate-mongoose is a migration framework for mongoose
I need a way to manage database migrations for mongoose models, run them from the CLI or programmatically, and keep track of which migrations have been applied. It should support both ESM and CommonJS, work with all major Node.js frameworks, and be flexible enough to handle complex migration scenarios.
Supports and tested with
{
"node": "20.x || 22.x || 24.x",
"mongoose": ">=6.6.0 <10"
}
CI tests against mongoose 6.12.2, 7.6.4, 8.23.0, and 9.4.1.
Features
- Stores migration state in MongoDB
- Flexible configuration using
migrate.json, migrate.ts, .env
- Utilizes mongoose models during migrations
- Supports async/await in migrations
- Run migrations from the CLI or programmatically
- Prune old migrations and sync new migrations
- Create custom templates for migrations
- Run individual migration up/down using -s, --single
- Supports ESM and CommonJS
Installation
mongoose is a peer dependency — install it alongside ts-migrate-mongoose.
npm install ts-migrate-mongoose mongoose
pnpm add ts-migrate-mongoose mongoose
yarn add ts-migrate-mongoose mongoose
bun add ts-migrate-mongoose mongoose
Or globally:
npm install -g ts-migrate-mongoose mongoose
pnpm add -g ts-migrate-mongoose mongoose
yarn global add ts-migrate-mongoose mongoose
bun add -g ts-migrate-mongoose mongoose
Example
Works with any Node.js framework — Express, Fastify, Koa, Hono, Nest, etc.
How to use it with:
Migrations and alias imports
If you are using alias imports in your project, you can use tsconfig.json paths to resolve them for your project.
Configuration
If you don't want to provide -d or --uri flag in CLI or Programmatic mode, you can configure it.
Create a migrate.json or migrate.ts or .env file in the root of your project:
{
"uri": "mongodb://localhost/my-db",
"collection": "migrations",
"migrationsPath": "./migrations",
"templatePath": "./migrations/template.ts",
"autosync": false
}
export default {
uri: "mongodb://localhost/my-db",
collection: "migrations",
migrationsPath: "./migrations",
templatePath: "./migrations/template.ts",
autosync: false,
connectOptions: {
autoIndex: true,
},
};
MIGRATE_MODE=development
If mode is set, it will look for .env.[mode] file in the root of your project
For example, if MIGRATE_MODE=development it will look for .env.development file
If mode is not set, it will look for .env file in the root of your project
.env
.env.local
.env.[mode]
.env.[mode].local
MIGRATE_MONGO_URI=mongodb://localhost/my-db
MIGRATE_MONGO_COLLECTION=migrations
MIGRATE_CONFIG_PATH=./migrate
MIGRATE_MIGRATIONS_PATH=./migrations
MIGRATE_TEMPLATE_PATH=./migrations/template.ts
MIGRATE_AUTOSYNC=false
| mode | MIGRATE_MODE | - | No | environment mode to use .env.[mode] file |
| uri | MIGRATE_MONGO_URI | - | Yes | mongo connection string |
| collection | MIGRATE_MONGO_COLLECTION | migrations | No | collection name to use for the migrations |
| configPath | MIGRATE_CONFIG_PATH | - | No | will lookup ./migrate[.ts,.js,.json] in root |
| migrationsPath | MIGRATE_MIGRATIONS_PATH | ./migrations | No | path to the migration files |
| templatePath | MIGRATE_TEMPLATE_PATH | - | No | template file to use when creating a migration |
| autosync | MIGRATE_AUTOSYNC | false | No | automatically sync new migrations without prompt |
| connectOptions | - | - | No | mongoose connection options (config file only) |
Getting started with the CLI
Explore and learn commands, rest of the tutorial will be using npm
npx migrate -h
pnpm migrate -h
yarn migrate -h
bun migrate -h
CLI migration tool for mongoose
Usage: migrate <command> [options]
Commands:
list list all migrations
create <migration-name> create a new migration file
up [migration-name] run all migrations or a specific migration if name provided
down <migration-name> roll back migrations down to given name
prune delete extraneous migrations from migration folder or database
Options:
-f, --config-path <path> path to the config file
-d, --uri <string> mongo connection string
-c, --collection <string> collection name to use for the migrations
-a, --autosync <boolean> automatically sync new migrations without prompt
-m, --migrations-path <path> path to the migration files
-t, --template-path <path> template file to use when creating a migration
--mode <string> environment mode to use .env.[mode] file
-s, --single run single migration (up/down only)
-h, --help display help
-v, --version display version
Before you start make sure you setup .env file or migrate.ts/json file so you don't need to provide -d on each command
npx migrate create add-users -d mongodb://localhost/my-db
In case you want to run just one migration up or down use option --single
npx migrate create first-migration
npx migrate create second-migration
npx migrate list
npx migrate up second-migration -s
npx migrate down second-migration -s
npx migrate up -s
Options override order
Note that options are overridden in the following order:
- Command line args > Env vars > Config file
Migration files
This example demonstrates how you can create a migration file using the CLI
By default, ts-migrate-mongoose assumes your migration folder exists (if it does not it will create one for you)
Here's an example of a migration created using:
npx migrate create first-migration
pnpm migrate create first-migration
yarn migrate create first-migration
bun migrate create first-migration
Executing the above command will create a migration file in the ./migrations folder with the following content:
- 1673525773572-first-migration.ts
import type { Connection } from 'mongoose'
export async function up (connection: Connection): Promise<void> {
}
export async function down (connection: Connection): Promise<void> {
}
Using mongoose models in your migrations
As long as you can import the references to your models you can use them in migrations
Below is an example of a typical setup in a mongoose project:
- models/User.ts - defines the User model
import { Schema, model, models } from 'mongoose'
interface IUser {
firstName: string
lastName?: string
}
export const UserSchema = new Schema<IUser>({
firstName: {
type: String,
required: true
},
lastName: {
type: String
}
})
export default models.User ?? model<IUser>('User', UserSchema)
- 1673525773572-first-migration-demo.ts - your migration file
import { UserSchema } from '../models/User'
import type { Connection } from 'mongoose'
export async function up(connection: Connection) {
const User = connection.model('User', UserSchema)
await User.create([
{
firstName: 'John',
lastName: 'Doe',
},
{
firstName: 'Jane',
lastName: 'Doe',
},
])
}
export async function down(connection: Connection) {
const User = connection.model('User', UserSchema)
await User.deleteMany({ firstName: { $in: ['Jane', 'John'] } }).exec()
}
Programmatic mode
Works with any Node.js framework — Express, Fastify, Koa, Hono, etc:
import { Migrator } from 'ts-migrate-mongoose'
const migrator = await Migrator.connect({
uri: 'mongodb://localhost:27017/my-db',
autosync: true,
})
await migrator.run('up')
await migrator.run('down', 'x')
await migrator.list()
await migrator.create('name')
await migrator.prune()
await migrator.close()
Express / Fastify / Koa / Hono
import { Migrator } from 'ts-migrate-mongoose'
const migrator = await Migrator.connect({
uri: process.env.MONGO_URI ?? 'mongodb://localhost:27017/my-db',
autosync: true,
})
await migrator.run('up')
await migrator.close()
app.listen(3000)
NestJS (because it's special)
Import MigrationModule from ts-migrate-mongoose/nest:
import { MigrationModule } from 'ts-migrate-mongoose/nest'
@Module({
imports: [
MongooseModule.forRoot(process.env.MONGO_URI),
MigrationModule.forRootAsync({
inject: [ConfigService],
useFactory: (config: ConfigService) => ({
uri: config.get<string>('MONGO_URI'),
autosync: true,
}),
}),
],
})
export class AppModule {}
Runs all pending up migrations on application bootstrap. For custom control:
MigrationModule.forRoot({
uri: process.env.MONGO_URI,
onBootstrap: async (migrator) => {
await migrator.run('down', 'test')
await migrator.prune()
await migrator.run('up')
},
})
See programmatic usage examples for the full API and more examples.
Contributing
Check CONTRIBUTING.md
License
This project is licensed under the MIT License - see the LICENSE file for details
Notes
- Currently, the
-d or --uri must include the database to use for migrations in the uri.
- Example:
-d mongodb://localhost:27017/development
- If you don't want to pass it every time feel free to use
migrate.ts or migrate.json config file or an environment variable
- Feel Free to check out the
/examples folder in the project to get a better idea of usage in Programmatic and CLI mode
Check my other projects