Beautiful, interactive database migrations for Go developers
A friendly wrapper around golang-migrate with short commands, YAML config, and a polished terminal UI.
go install github.com/taqnihub/gomigrate@latest# 1. Install the CLI
go install github.com/taqnihub/gomigrate@latest
# 2. Verify it's installed
gomigrate --version
# 3. Initialize gomigrate in your project (interactive wizard)
gomigrate init
# 4. Create your first migration (generates .up.sql and .down.sql files)
gomigrate create add_users_table
# 5. Edit the generated SQL files in ./db/migrations/
# (add your CREATE TABLE, ALTER TABLE, etc.)
# 6. Check what's pending
gomigrate status
# 7. Apply all pending migrations
gomigrate up
# 8. Verify everything was applied
gomigrate status
# 9. If you need to undo the last migration
gomigrate down
# 10. Or launch the interactive TUI menu
gomigrateThat's it. No Docker commands. No 200-character invocations. Just works.
Database migrations don't have to be painful. Compare:
Before β raw golang-migrate:
docker run -it --rm --network host --volume ./db:/db \
migrate/migrate:v4.19.0 \
-path=/db/migrations \
-database "mysql://root:password@localhost:3306/ecomm" \
upAfter β gomigrate:
gomigrate up- π¨ Beautiful output β colored, styled, easy to read
- π₯οΈ Interactive TUI β run
gomigratewith no args for a menu - π YAML config β
.gomigrate.ymlkeeps credentials out of shell history - π Env var support β override any setting with
GOMIGRATE_*variables - π‘οΈ Safety first β duplicate detection, dirty-state recovery, clear errors
- π¦ Library mode β import
github.com/taqnihub/gomigratein your Go code - π¬ π MySQL & PostgreSQL β full support for both
With Go 1.22+ installed, one command:
go install github.com/taqnihub/gomigrate@latestVerify it works:
gomigrate --versionNote: Make sure
$(go env GOPATH)/binis in your$PATH. Add this to your shell config ifgomigrateisn't found after install:export PATH=$PATH:$(go env GOPATH)/bin
Add GoMigrate to your Go project:
go get github.com/taqnihub/gomigrate@latestThen import in your code:
import (
"github.com/taqnihub/gomigrate/config"
"github.com/taqnihub/gomigrate/migrate"
)See Library Usage below for full examples.
Only needed if you want to modify the code or submit a PR:
git clone https://github.com/taqnihub/gomigrate.git
cd gomigrate
go build -o gomigrate .
./gomigrate --helpJust run gomigrate with no arguments:
gomigrateYou'll get a menu to navigate with arrow keys.
| Command | Description | Example |
|---|---|---|
gomigrate |
Launch interactive TUI menu | gomigrate |
gomigrate init |
Interactive wizard to create .gomigrate.yml |
gomigrate init |
gomigrate init --force |
Overwrite existing config | gomigrate init --force |
gomigrate create <name> |
Generate up/down SQL files | gomigrate create add_users_table |
gomigrate up |
Apply all pending migrations | gomigrate up |
gomigrate up [n] |
Apply the next N migrations | gomigrate up 3 |
gomigrate down |
Revert the last migration | gomigrate down |
gomigrate down [n] |
Revert the last N migrations | gomigrate down 2 |
gomigrate down --all |
Revert ALL applied migrations (destructive) | gomigrate down --all |
gomigrate status |
Show applied vs pending migrations | gomigrate status |
gomigrate force <version> |
Reset migration version (fix dirty state) | gomigrate force 20260417103045 |
gomigrate --version |
Show gomigrate version | gomigrate --version |
gomigrate --help |
Show help for all commands | gomigrate --help |
gomigrate <cmd> --help |
Show help for a specific command | gomigrate up --help |
| Flag | Short | Description | Example |
|---|---|---|---|
--config <path> |
-c |
Path to config file | gomigrate -c ./prod.yml up |
--driver <name> |
-d |
Override database driver | gomigrate -d postgres status |
--dir <path> |
Override migrations directory | gomigrate --dir ./db/migs up |
|
--verbose |
-v |
Show detailed output | gomigrate -v up |
--no-interactive |
Disable TUI & colors (CI-friendly) | gomigrate --no-interactive up |
GoMigrate reads config from (in priority order):
- CLI flags (
--driver mysql,--dir ./migrations, etc.) - Environment variables (
GOMIGRATE_*) .gomigrate.ymlin the current directory.gomigrate.ymlin your home directory- Sensible defaults
.gomigrate.yml:
driver: mysql # mysql or postgres
host: localhost
port: 3306
database: myapp
user: root
password: secret
migrations_dir: ./db/migrations
# Optional
ssl_mode: disable # disable, require, verify-full
timezone: UTC
lock_timeout: 15sPerfect for CI/CD:
export GOMIGRATE_DRIVER=postgres
export GOMIGRATE_HOST=prod-db.example.com
export GOMIGRATE_PASSWORD=$DB_PASSWORD
gomigrate upGoMigrate is also a Go library. Import it in your code:
package main
import (
"log"
"github.com/taqnihub/gomigrate/config"
"github.com/taqnihub/gomigrate/migrate"
)
func main() {
// Load config from .gomigrate.yml or env vars
cfg, err := config.Load("")
if err != nil {
log.Fatal(err)
}
// Create engine
engine, err := migrate.New(cfg)
if err != nil {
log.Fatal(err)
}
defer engine.Close()
// Apply all pending migrations
if err := engine.Up(); err != nil {
log.Fatal(err)
}
// Check current version
version, dirty, _ := engine.Version()
log.Printf("at version %d (dirty: %v)", version, dirty)
}func main() {
cfg, _ := config.Load("")
engine, _ := migrate.New(cfg)
defer engine.Close()
// Auto-apply pending migrations when the app starts
if err := engine.Up(); err != nil && !errors.Is(err, migrate.ErrNoChange) {
log.Fatal("migration failed:", err)
}
// ... start your web server ...
}Migration files are plain SQL. GoMigrate creates pairs of files:
db/migrations/
βββ 20260417100000_add_users_table.up.sql
βββ 20260417100000_add_users_table.down.sql
up.sql β apply the change:
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(255) NOT NULL UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);down.sql β undo the change:
DROP TABLE IF EXISTS users;| Pattern | Example |
|---|---|
create_<table>_table |
create_users_table |
add_<column>_to_<table> |
add_email_to_users |
drop_<column>_from_<table> |
drop_legacy_id_from_orders |
add_index_<n> |
add_index_email_to_users |
| Feature | gomigrate | golang-migrate CLI | goose |
|---|---|---|---|
| Interactive TUI | β | β | β |
| YAML config file | β | β | β |
| Env var support | β | β | β |
| Pretty colored output | β | β | |
| Duplicate detection | β | β | β |
| Library mode | β | β | β |
| MySQL support | β | β | β |
| PostgreSQL support | β | β | β |
- Go 1.22 or higher
- MySQL or PostgreSQL (for testing)
git clone https://github.com/taqnihub/gomigrate.git
cd gomigrate
go mod download
make buildmake build # Build the binary
make test # Run unit tests
make test-cover # Run tests with coverage report
make install # Install to $GOPATH/bin
make clean # Remove build artifactsgomigrate/
βββ cmd/ # Cobra CLI commands
βββ config/ # Config loading (public library package)
βββ migrate/ # Migration engine (public library package)
βββ internal/tui/ # TUI components (private)
βββ main.go # CLI entry point
Contributions welcome! Please:
- Fork the repo
- Create a feature branch (
git checkout -b feat/amazing-feature) - Make your changes
- Add tests
- Run
make testto verify - Commit with conventional messages (
feat:,fix:,docs:, etc.) - Push and open a PR
Found a bug? Have a feature request? Open an issue.
MIT Β© taqnihub
Built with:
- golang-migrate β the powerful migration engine under the hood
- cobra β CLI framework
- viper β config management
- bubbletea β TUI framework
- lipgloss β terminal styling
- huh β interactive forms
If gomigrate saves you time, consider giving it a β on GitHub!