Node Migrate

2.1.0 · maintenance · verified Sun Apr 19

Node Migrate is an abstract migration framework designed for Node.js applications, offering both a command-line interface (CLI) and a programmatic API for managing schema or data changes. As of its latest version, 2.1.0, it provides a flexible mechanism to create, apply, and rollback migrations, supporting various database types through custom logic within migration files. It distinguishes itself by providing a simple, generator-based approach to migration file creation, allowing users to define their own templates and compilers (like Babel or TypeScript) for modern JavaScript features. The package prioritizes flexibility, enabling developers to integrate it into diverse project setups. Its release cadence is not explicitly stated but appears to be stable with infrequent major updates, making it a reliable choice for established Node.js projects requiring robust migration management.

Common errors

Warnings

Install

Imports

Quickstart

This example demonstrates the programmatic API of `migrate`, loading migrations from a temporary directory and executing them against a mock database object, including handling both callback-based and async functions.

import migrate from 'migrate';
import { resolve } from 'path';
import { existsSync, mkdirSync, writeFileSync } from 'fs';

// Mock database object shared across migrations.
// In a real application, this would be your actual database client or ORM connection.
const mockGlobalDb: { users?: string[]; products?: string[]; } = {};

// Paths for migrations and state store
const migrationsDir = resolve('./migrations_quickstart_simple');
const stateStorePath = resolve('./.migrate_quickstart_simple_state');

// Ensure directories and state file exist
if (!existsSync(migrationsDir)) mkdirSync(migrationsDir);
if (!existsSync(stateStorePath)) {
  writeFileSync(stateStorePath, JSON.stringify({ lastRun: null, migrations: [] }), 'utf8');
}

// Create mock migration files
const createUsersMigrationContent = `
// This 'db' variable refers to 'mockGlobalDb' from the quickstart example.
// In real migrations, you would typically import or pass your database client.
exports.up = function (next) {
  console.log('Running UP: Create Users');
  // Simulate a database operation
  module.parent.exports.mockGlobalDb.users = ['Alice', 'Bob'];
  next();
};

exports.down = function (next) {
  console.log('Running DOWN: Drop Users');
  // Simulate rolling back a database operation
  delete module.parent.exports.mockGlobalDb.users;
  next();
};
`;

const addProductsMigrationContent = `
// This 'db' variable refers to 'mockGlobalDb' from the quickstart example.
exports.up = async function () { // Using async/await, no 'next' callback needed
  console.log('Running UP: Add Products');
  // Simulate a database operation
  module.parent.exports.mockGlobalDb.products = ['Laptop', 'Mouse'];
};

exports.down = async function () {
  console.log('Running DOWN: Remove Products');
  // Simulate rolling back a database operation
  delete module.parent.exports.mockGlobalDb.products;
};
`;

// Write the migration files for the quickstart to execute
const ts1 = Date.now() - 10000;
const ts2 = Date.now();
writeFileSync(resolve(migrationsDir, `${ts1}-create-users.js`), createUsersMigrationContent, 'utf8');
writeFileSync(resolve(migrationsDir, `${ts2}-add-products.js`), addProductsMigrationContent, 'utf8');

// Expose mockGlobalDb so migration files (which are 'require'd) can access it.
// This is a quickstart hack; in a real app, you'd pass your DB client correctly.
Object.assign(module.exports, { mockGlobalDb });

console.log('Initializing migrations...');
migrate.load({
  stateStore: stateStorePath,
  migrationsDirectory: migrationsDir
}, function (err, set) {
  if (err) {
    console.error('Failed to load migrations:', err);
    process.exit(1);
  }

  console.log('Migrations loaded. Current status:');
  set.migrations.forEach(m => console.log(`- ${m.title}: ${m.state}`));

  set.up(function (err) {
    if (err) {
      console.error('Failed to run UP migrations:', err);
      process.exit(1);
    }
    console.log('\nAll UP migrations successfully executed!');
    console.log('Current mock database state:', mockGlobalDb);

    // To demonstrate rolling back, uncomment the following:
    /*
    console.log('\nRunning DOWN to "create-users" migration...');
    set.down('create-users', function(err) {
      if (err) {
        console.error('Failed to run DOWN migrations:', err);
        process.exit(1);
      }
      console.log('Successfully rolled back to "create-users"!');
      console.log('Current mock database state after partial DOWN:', mockGlobalDb);
    });
    */
  });
});

view raw JSON →