Configuration
mongo-migrate-kit resolves configuration from four sources, in priority order:
CLI flags > Environment variables > Config file > DefaultsA config file is never required — env vars alone are always sufficient.
Config file
On startup, mmk looks in the current working directory for the first of:
mmk.config.tsmmk.config.jsmmk.config.json
Generate one with mmk init. Override discovery with --config <path>.
export default {
uri: process.env.MMK_URI ?? 'mongodb://localhost:27017',
dbName: 'my_app',
migrationsDir: './migrations',
migrationsCollection: '_mmk_migrations',
strict: false,
useTransaction: false,
createExtension: 'js',
};import type { MmkConfig } from 'mongo-migrate-kit';
const config: Partial<MmkConfig> = {
uri: process.env.MMK_URI ?? 'mongodb://localhost:27017',
dbName: 'my_app',
migrationsDir: './migrations',
createExtension: 'ts',
};
export default config;{
"uri": "mongodb://localhost:27017",
"dbName": "my_app",
"migrationsDir": "./migrations"
}Async / factory config (secret managers)
A .ts/.js config may export default a function (sync or async) that returns the config. This is the dependency-free way to load a connection from a secret manager at runtime — the library ships no cloud SDKs, you bring your own inside the function:
import type { MmkConfigInput } from 'mongo-migrate-kit';
const loadConfig: MmkConfigInput = async () => {
const { uri, dbName } = await fetchFromSecretsManager(); // your code
return { uri, dbName, migrationsDir: './migrations' };
};
export default loadConfig;Generate a ready-made AWS Secrets Manager template with mmk init --secret-provider (swap the body for Google/Vault/Azure/any source — it just must return { uri, dbName }).
All options
| Option | Type | Default | Description |
|---|---|---|---|
uri | string | — | MongoDB connection URI (required) |
dbName | string | — | Database name (required) |
migrationsDir | string | './migrations' | Directory holding migration files |
migrationsCollection | string | '_mmk_migrations' | Collection storing the changelog |
lockCollection | string | '_mmk_locks' | Collection used for the concurrency lock |
lockTTLSeconds | number | 60 | Seconds before a lock is considered stale |
strict | boolean | false | Abort (vs. warn) on a checksum mismatch |
useTransaction | boolean | false | Wrap every migration in a transaction globally |
fileExtensions | string[] | ['.ts', '.js'] | Extensions scanned in the migrations dir |
createExtension | 'ts' | 'js' | 'js' | Default file type for mmk create |
sequential | boolean | false | Use 0001- numbering instead of timestamps |
templatePath | string | — | Path to a custom migration template |
mongoose | Mongoose | — | Mongoose instance, if your migrations use it |
mongoClientOptions | MongoClientOptions | — | Extra options merged into the MongoClient (TLS, timeouts, auth, read/write prefs) |
hooks | MigrationHooks | — | Lifecycle hooks |
logger | MmkLogger | null | built-in | Custom logger; null silences all output |
Connection hardening
mmk builds the MongoClient with safe defaults so a wrong URI fails fast:
serverSelectionTimeoutMSandconnectTimeoutMSof10000— an unreachable host errors in seconds instead of hanging.retryWrites: true.- No client-wide write concern is imposed — your migration operations keep whatever durability your URI/cluster specifies (so a deliberate
?w=1for a fast bulk migration is respected). - Durability is pinned only where correctness depends on it: the lock collection (
_mmk_locks) and changelog (_mmk_migrations) are always written withw: 'majority'(the lock is also read withreadConcern: 'majority') at the collection level, so mutual exclusion and the audit trail survive a primary failover regardless of your URI.
mongoClientOptions is merged last, so it overrides the defaults above. Use it to enable TLS, tune timeouts, or set auth and read preferences for your production cluster:
// mmk.config.js
export default {
uri: process.env.MMK_URI,
dbName: 'my_app',
mongoClientOptions: {
tls: true,
serverSelectionTimeoutMS: 5000,
readPreference: 'primary',
},
};Credentials in errors are redacted
The native driver often embeds the connection string in its error messages. mmk scrubs any user:pass@ from connection errors before they reach logs, --json output, or an error's context, so a failed connection never leaks your password.
Environment variables
Every core option has an MMK_* variable. These override the config file:
| Env var | Maps to |
|---|---|
MMK_URI | uri |
MMK_DB | dbName |
MMK_MIGRATIONS_DIR | migrationsDir |
MMK_COLLECTION | migrationsCollection |
MMK_LOCK_COLLECTION | lockCollection |
MMK_LOCK_TTL | lockTTLSeconds |
MMK_STRICT | strict |
MMK_USE_TRANSACTION | useTransaction |
MMK_SEQUENTIAL | sequential |
MMK_CREATE_EXTENSION | createExtension |
.env files are loaded automatically (via dotenv) before env vars are read.
# .env
MMK_URI=mongodb://localhost:27017
MMK_DB=my_appGlobal CLI flags
These flags work on every command and have the highest precedence:
| Flag | Overrides |
|---|---|
--uri <uri> | MMK_URI / uri |
--db <name> | MMK_DB / dbName |
--dir <path> | MMK_MIGRATIONS_DIR / migrationsDir |
--config <path> | Config file auto-discovery |
mmk up --uri "mongodb://localhost:27017" --db my_app --dir ./db/migrations