| Crates.io | migrate |
| lib.rs | migrate |
| version | 0.3.2 |
| created_at | 2020-08-16 14:17:59.282896+00 |
| updated_at | 2026-01-22 21:44:19.523292+00 |
| description | Generic file migration tool for applying ordered transformations to a project directory |
| homepage | |
| repository | https://github.com/glideapps/migrate |
| max_upload_size | |
| id | 277239 |
| size | 117,994 |
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.
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/
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
Requires Rust:
cargo install migrate
cargo install --git https://github.com/glideapps/migrate
migrate status
migrate up
migrate up --dry-run
# 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
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
#!/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
#!/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.
| Command | Description |
|---|---|
migrate status |
Show applied and pending migrations |
migrate up |
Apply all pending migrations |
migrate create <name> |
Create a new migration file |
| 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) | - |
bash - Shell script (.sh)ts - TypeScript via tsx (.ts)python - Python 3 (.py)node - Node.js (.js)ruby - Ruby (.rb)# 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