Miglite – raw SQL migrations for Go projects

jxia1 pts0 comments

Inhere's Site • miglite: raw SQL migrations for Go projectsSkip to contentmiglite: raw SQL migrations for Go projects<br>Inhere 18th Jun 2026•5 min read•Tags: gookit, golang, miglite, databaseDatabase migration tools usually pick one of two lanes. Some describe schema changes in their own DSL and generate SQL for you. Others take the SQL you already wrote, run it in order, and record what has been applied.github.com/gookit/miglite stays in the second lane. It does not replace SQL, and the library does not pull database drivers into your dependency tree by default. It discovers migration files, parses UP/DOWN sections, runs SQL in a transaction, and records the migration status in the database.<br>Project: https://github.com/gookit/migliteAPI docs: https://pkg.go.dev/github.com/gookit/migliteLatest release: v0.4.0 Why another migration tool<br>Go already has solid migration tools, including golang-migrate, goose, and dbmate. miglite is not trying to replace them. It is aimed at the smaller case:The project already maintains raw SQL files.The service already has a database driver, and the migration library should not add another one.Deployment should work with DATABASE_URL and MIGRATIONS_PATH.Migration files may live in multiple module directories, but execution order still has to be consistent.That is a common shape for internal tools, small services, and plugin-style projects. The migration layer should not become heavier than the code it is supporting. Migration files are plain SQL files<br>miglite uses a fixed filename format:YYYYMMDD-HHMMSS-{migration-name}.sqlFor example:migrations/20251105-102325-create-users-table.sqlEach file has two sections:-- Migrate:UP<br>CREATE TABLE users (<br>id INTEGER PRIMARY KEY,<br>name TEXT NOT NULL,<br>created_at DATETIME NOT NULL<br>);

-- Migrate:DOWN<br>DROP TABLE users;UP is required. DOWN is optional. The up command runs the UP section, and the down command runs the DOWN section.There is not much magic in this format, which is the point. A DBA can read it. A production incident can be debugged by copying the SQL into the database console. No one has to learn a migration DSL before understanding what will run. The CLI covers the normal path<br>Install the command:go install github.com/gookit/miglite/cmd/miglite@latestYou can also install it with eget:eget install gookit/migliteCreate a migration file:miglite create add-users-tableInitialize the migration table and apply pending migrations:miglite init # optional; up initializes the schema if needed<br>miglite upCheck status:miglite statusRollback the latest migration:miglite downFor CI or deployment scripts, skip per-file confirmation:miglite up --yesRun only the first two pending migrations:miglite up --number 2 --yesThose commands cover the main workflow. miglite exec can run a SQL statement or SQL file directly, and miglite show can inspect tables and table schemas during local debugging. Configuration can be a file or just environment variables<br>The smallest setup needs only two environment variables:DATABASE_URL="sqlite://var/app.db"<br>MIGRATIONS_PATH="./migrations"MySQL example:DATABASE_URL="mysql://user:passwd@tcp(127.0.0.1:3306)/app_db?charset=utf8mb4&parseTime=True&loc=Local"<br>MIGRATIONS_PATH="./migrations/mysql"PostgreSQL example:DATABASE_URL="postgres://host=localhost port=5432 user=app password=secret dbname=app_db sslmode=disable"<br>MIGRATIONS_PATH="./migrations/postgres"If you prefer a config file, use miglite.yaml:database:<br>driver: sqlite<br>dsn: ./sqlite_test.db

migrations:<br>path: ./migrationsBy default, miglite tries these files in the current directory:.env.local<br>.env.dev<br>.env<br>miglite.yaml<br>miglite.local.yamlConfig values can include environment placeholders:database:<br>driver: postgres<br>host: localhost<br>port: 5432<br>user: ${PG_DB_USER}<br>password: ${PG_DB_PWD | pg1234abcd}<br>dbname: pg_test_db<br>ssl_mode: disableThat default-value syntax is useful for local development. A laptop can run with a fallback password, while deployment injects the real value. Multiple migration directories work for modular projects<br>Migration paths can be comma-separated:MIGRATIONS_PATH="./migrations/core,./migrations/billing,./migrations/report"miglite scans the directories, then sorts all SQL files by filename prefix before execution.Recursive scanning is enabled by default. Directories that start with _ are ignored:migrations/<br>core/<br>20260101-100000-create-users.sql<br>billing/<br>20260101-101000-create-orders.sql<br>_backup/<br>20240101-100000-old.sqlFiles under _backup will not be executed as migrations. That convention is boring, but useful when old SQL needs to stay nearby without being picked up by the runner.Migration paths can also include {driver}:migrations:<br>path: ./migrations/{driver}That lets a project keep SQLite, MySQL, and PostgreSQL SQL files in separate directories while sharing the same config shape. SQL and migration records run in the same transaction<br>For each migration file, miglite opens a transaction, runs the UP or DOWN SQL, writes the migration record, then...

miglite migration migrations files file gookit

Related Articles