The Standalone Airway CLI
Airway ships as a standalone, go-installable command-line tool. One airway binary covers the whole project lifecycle: scaffolding a new application, generating code, managing the database, and starting the server.
go install github.com/daqing/airway@latestThis installs the airway command into your Go bin directory (make sure $(go env GOPATH)/bin is on your PATH). Inside any Airway project the same commands also run as go run . <command>.
Quick start: from zero to a running app
airway new myapp # or: airway new github.com/me/myapp
cd myapp
cp .env.example .env # set DSN and PORT
airway db:create
airway db:migrate
go run . server # start the HTTP serverairway new scaffolds a complete project skeleton (routes, models, views, WebSocket hub, storage, Docker setup) from an embedded template, replaces the placeholder with your module path, and runs go mod tidy. The target directory is the last path segment of the module path (github.com/me/myapp → ./myapp) and must not already exist as a non-empty directory.
How the binary dispatches commands
The airway binary is a CLI first:
airway serverstarts the HTTP server (it requiresAIRWAY_ENV; whenAIRWAY_ENV=local,.envis loaded automatically).- Every other argument is dispatched to the CLI. All CLI commands auto-load
.envfrom the current directory, so run them from your project root. - Running
airwaywith no arguments prints usage.
The framework repository itself behaves the same way: go run . server starts the server, go run . <command> runs a CLI command. (A project generated by airway new additionally starts the server when its binary is run with no arguments.)
Command reference
airway new <module-path> # scaffold a new project
airway server # start the HTTP server
airway generate [action|api|model|migration|service|cmd] [params]
airway db:create
airway db:drop
airway db:migrate [version]
airway db:rollback [step]
airway db:status
airway schema:dump
airway schema:show
airway engine new <module-path> # scaffold a new engine module
airway engine:list
airway engine:install [name]
airway upload [key] /path/to/file
airway repl # project binary only
airway version
airway help # or -h / --helpgenerate can be shortened to g (airway g api admin).
Generators
Generators read the module path from the current directory's go.mod, so generated code imports your project's packages — run them from the project root. Generators never overwrite existing files.
airway generate api admin # app/api/admin_api/ (routes + index action)
airway generate action admin show # new action in an existing API module
airway generate model post # app/models/post.go (with REPL registration)
airway generate service post title:string # CRUD service in app/services/
airway generate cmd post title published # custom CLI helper in cmd/
airway generate migration create_posts # SQL up/down pair in db/migrate/After generate api, remember to wire the generated Routes(...) into config/routes.go.
Database and migrations
Migration files are plain SQL pairs under db/migrate/:
<timestamp>_<name>.up.sql— the forward migration<timestamp>_<name>.down.sql— the rollback migration
Because migrations are plain SQL files, the standalone CLI can migrate any Airway project without compiling the project itself. Each migration runs in a transaction, applied versions are tracked in the schema_migrations table, and db:migrate / db:rollback refresh the db/schema.json snapshot automatically. Migrations work with PostgreSQL, MySQL, and SQLite; the driver is inferred from the DSN scheme.
airway db:migrate # apply all pending migrations
airway db:migrate 20260327120000 # migrate up to a specific version
airway db:rollback # roll back the latest migration
airway db:rollback 3 # roll back three steps
airway db:status # show applied/pending per migrationDatabase commands resolve the DSN from the first of these environment variables that is set: DSN, AIRWAY_DSN, AIRWAY_DB_DSN (legacy), AIRWAY_PG (legacy). Since the CLI auto-loads .env, setting DSN there is enough.
The older Go DSL migration mechanism (schema.RegisterChange) is still supported, but DSL migrations only run when compiled into the binary that executes them. If the CLI finds timestamped .go migration files under db/migrate, it prints a warning — prefer SQL migrations so the standalone CLI can run them.
Schema snapshot
airway schema:dump # inspect the database and write db/schema.json
airway schema:show # print the current db/schema.jsonEngines
Scaffold a new engine module (works with the globally installed airway — it only writes files):
airway engine new im # directory: im, engine name: im
airway engine new github.com/me/airway-im-engine # name derived from the last path segmentEngines are optional feature modules enabled via blank imports in engines.go (see docs/engine.md):
go run . engine:list # list registered engines and mount paths
go run . engine:install <name> # copy an engine's embedded SQL migrations into db/migrate/Engines register at compile time, so run these through the project binary (go run . ...): the globally installed airway can only see the engines compiled into itself. engine:install assigns fresh timestamps to the copied migrations and skips files that are already installed; afterwards they are ordinary migrations managed by db:migrate / db:rollback / db:status.
File upload
airway upload /tmp/foo.png # key derived from the path (tmp/foo.png)
airway upload images/foo.png /tmp/foo.png # explicit storage keyUploads go through the storage configured in .env (STORAGE_DRIVER, STORAGE_ROOT, cloud credentials, ...).
REPL
go run . replThe REPL only sees the models compiled into the binary you run — project models register via registerREPLModel in app/models, which delegates to lib/replreg. Use go run . repl inside your project; the globally installed airway repl only sees the framework's built-in models.
Global airway vs. the project binary
Some commands depend on code compiled into the running binary (models, engines, Go DSL migrations). Use the right binary for each:
| Command | Global airway | Project binary (go run . ...) |
|---|---|---|
new, generate, server | yes | yes |
engine new | yes | yes |
db:create / db:drop / db:migrate / db:rollback / db:status | yes (SQL migrations) | yes |
schema:dump / schema:show, upload, version | yes | yes |
repl | framework's built-in models only | use this — sees your project models |
engine:list / engine:install | engines compiled into airway itself | use this — sees your project's engines |
Compatibility
The pre-0.5 form airway cli <command> still works as an alias for airway <command>. airway plugin install is deprecated — use engines instead (see docs/engine.md).
See also: docs/cli.md for the full scaffolding guide with a step-by-step feature example.