migrate

Crates.iomigrate
lib.rsmigrate
version0.3.2
created_at2020-08-16 14:17:59.282896+00
updated_at2026-01-22 21:44:19.523292+00
descriptionGeneric file migration tool for applying ordered transformations to a project directory
homepage
repositoryhttps://github.com/glideapps/migrate
max_upload_size
id277239
size117,994
Ryan Daigle (rwdaigle)

documentation

README

migrate

A generic file migration tool that applies ordered transformations to a project directory. Think database migrations, but for files and project setup. Migrations can be written in any language (bash, TypeScript, Python, etc.) using shebangs.

Install

Option 1: Download binary (easiest)

Download the pre-built binary for your platform from GitHub Releases, then move it to a directory in your PATH:

# Example for macOS (Apple Silicon)
curl -L https://github.com/glideapps/migrate/releases/latest/download/migrate-aarch64-apple-darwin -o migrate
chmod +x migrate
sudo mv migrate /usr/local/bin/

Option 2: cargo-binstall (recommended if you have Rust)

If you have Rust installed, cargo-binstall downloads pre-built binaries:

# Install cargo-binstall first (if you don't have it)
cargo install cargo-binstall

# Then install migrate
cargo binstall migrate

Option 3: cargo install

Requires Rust:

cargo install migrate

Option 4: Build from source

cargo install --git https://github.com/glideapps/migrate

Usage

Check migration status

migrate status

Apply pending migrations

migrate up

Preview changes without applying

migrate up --dry-run

Create a new migration

# Create a bash migration (default)
migrate create add-prettier

# Create a TypeScript migration
migrate create add-config --template ts

# Create with description
migrate create add-prettier -d "Add Prettier configuration"

# List available templates
migrate create --list-templates

Writing Migrations

Migration files use the format XXXXX-name.{sh,ts,py,...} where XXXXX is a 5-character base36 version automatically generated by migrate create. The version encodes the creation timestamp, ensuring migrations sort chronologically.

Migrations are executable files that receive context via environment variables:

MIGRATE_PROJECT_ROOT=/path/to/project      # Absolute path to project root
MIGRATE_MIGRATIONS_DIR=/path/to/migrations # Where migration files live
MIGRATE_ID=1fb2g-initial-setup             # Current migration ID (includes version)
MIGRATE_DRY_RUN=true|false                 # Whether this is a dry run

Bash example

#!/usr/bin/env bash
set -euo pipefail
# Description: Add TypeScript configuration

cd "$MIGRATE_PROJECT_ROOT"
cat > tsconfig.json << 'EOF'
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "strict": true
  }
}
EOF

TypeScript example

#!/usr/bin/env -S npx tsx
// Description: Add configuration file

import * as fs from 'fs/promises';
import * as path from 'path';

const projectRoot = process.env.MIGRATE_PROJECT_ROOT!;

const config = {
  version: 1,
  features: ['auth', 'api']
};

await fs.writeFile(
  path.join(projectRoot, 'config.json'),
  JSON.stringify(config, null, 2)
);

Migrations run in order by their version prefix (e.g., 1fb2g-) and are tracked in a .history file.

CLI Reference

Command Description
migrate status Show applied and pending migrations
migrate up Apply all pending migrations
migrate create <name> Create a new migration file

Options

Option Description Default
-r, --root <path> Project root directory .
-m, --migrations <path> Migrations directory migrations
--dry-run Preview changes (up only) false
-t, --template <name> Template to use (create only) bash
-d, --description <text> Migration description (create only) -
--list-templates List available templates (create only) -

Available Templates

  • bash - Shell script (.sh)
  • ts - TypeScript via tsx (.ts)
  • python - Python 3 (.py)
  • node - Node.js (.js)
  • ruby - Ruby (.rb)

Development

# Clone and setup
git clone <repo-url>
cd migrate
./scripts/setup     # Enable git hooks, fetch deps, build, test

# Common commands
cargo build         # Build debug binary
cargo nextest run   # Run tests
cargo fmt           # Format code
cargo clippy        # Lint
cargo run -- status # Run CLI locally

# Build release
cargo build --release
Commit count: 13

cargo fmt