go install github.com/AlexGalhardo/vukem/cmd/vukem@latest
vukem listvukem works on files and shells out to the standard Go toolchain; it never imports your code. Commands it does not know are handed to your app binary, so vukem migrate works like php artisan migrate.
Commands#
| Command | Description |
|---|---|
vukem new <name> [--api | --templ | --inertia react|vue|svelte] [--module path] [--pm npm|bun|pnpm|yarn] [--no-install] [--framework dir] | Create a project from a starter (prompts for the stack on a terminal); run go mod tidy, write APP_KEY, install frontend dependencies with --pm (default npm), git init |
vukem install:auth [--social github,google,…] [--2fa] | Add login, registration, email verification and password reset (Authentication), optionally social login and two-factor |
vukem install:inertia --force [--react|--vue|--svelte] | Turn the HTMX starter into an Inertia app |
vukem install:admin, vukem make:admin-resource <Model> | Admin panel and its resources |
vukem install:billing | Stripe subscriptions (needs install:auth) |
vukem make:proto <Name>, vukem codegen:rpc [--protoc] | gRPC service skeleton and code generation |
vukem down [--secret s], vukem up | Maintenance mode: 503 with Retry-After; /<secret> sets a signed bypass cookie |
vukem boost:install | Guidelines, skills and the boost:mcp MCP server for AI coding agents |
vukem install:api | Add API tokens, /api/v1, CORS and rate limiting (REST APIs) |
vukem serve [--poll 500ms] [--no-vite] | Build and run cmd/app; rebuild and restart when .go, .templ, go.mod, go.sum or .env change |
vukem build [-o bin/app] | go tool templ generate when .templ files exist, vite build when a vite.config.* exists, then go build -trimpath -ldflags="-s -w" |
vukem key:generate [--show] [--force] | Write APP_KEY to .env (created from .env.example when missing) |
vukem key:rotate | Write a new APP_KEY to .env and move the old one to the front of APP_PREVIOUS_KEYS (key rotation) |
vukem version | Print the CLI version |
vukem list, vukem help <command> | List commands, or show one command's flags |
Flags may come before or after arguments: vukem make:model Post -m -c equals vukem make:model -m -c Post.
Generators#
| Command | Creates |
|---|---|
make:controller <Name> [--resource] [--api] | app/controllers/<name>_controller.go: an Index action, the 7 resource actions, or the 5 JSON actions |
make:model <Name> [-m] [-f] [-c] | app/models/<name>.go; -m a create_<table>_table migration, -f a factory in database/factories/, -c a resource controller |
make:migration <name> | database/migrations/<timestamp>_<name>.go, appended to migrations.All() |
make:middleware <Name> | app/middleware/<name>.go with a func(http.Handler) http.Handler |
make:request <Name> | app/requests/<name>.go: input struct and z.For schema |
make:command <Name> | app/commands/<name>.go, appended to bootstrap.Commands() |
make:provider <Name> | app/providers/<name>_provider.go, appended to bootstrap.Providers() |
make:test <Name> | tests/<name>_test.go using vukemtest |
make:resource <Name> | app/resources/<name>.go: JSON transformer and api.Map list helper |
make:factory <Name> | database/factories/<name>_factory.go with factory.New |
make:seeder <Name> | database/seeders/<name>_seeder.go, appended to seeders.All() |
make:policy <Name> | app/policies/<name>_policy.go, appended to policies.All() |
make:mail <Name> | app/mail/<name>.go and resources/views/mail/<name>.html |
make:event <Name> | app/events/<name>.go |
make:listener <Name> --event <Event> [--async|--queued] | app/listeners/<name>.go, appended to listeners.All() (--queued runs it as a queue job) |
make:job <Name> | app/jobs/<name>.go (job type, Kind, handler built from the app), appended to jobs.All(app) |
- Generated Go is
gofmted. Existing files are never overwritten without--force. - Conventional suffixes are optional:
PostController,BillingProviderandSendReportsCommandwork as names. - Registration edits the target file through its AST and adds imports; running a generator twice does not register twice. If the file was restructured, the generator prints the line to add by hand.
Custom stubs#
Stubs are text/template files embedded in the CLI. Put a file with the same name in your project's stubs/ directory to override one (controller.go.tmpl, model.go.tmpl, migration.go.tmpl, middleware.go.tmpl, request.go.tmpl, command.go.tmpl, provider.go.tmpl, factory.go.tmpl, seeder.go.tmpl, resource.go.tmpl, policy.go.tmpl, mail.go.tmpl, mail.html.tmpl, event.go.tmpl, listener.go.tmpl, job.go.tmpl, test.go.tmpl). Available data: .Name (Pascal), .Snake, .Kebab, .Camel, .Plural, .Module, and .Table, .Timestamp, .ID, .Func, .Resource, .API where relevant. Unknown keys are errors.
App commands#
Any other command runs inside your application:
vukem migrate
vukem migrate:status --json
vukem route:list
vukem queue:work
vukem schedule:list
vukem openapi:export > openapi.json
vukem about
vukem reports:send --dry-run # your own commandvukem builds cmd/app into .vukem/bin/app and runs it with the same arguments. The binary is rebuilt only when a .go, go.mod or go.sum file is newer, so repeated commands start instantly. Built-in app commands: migrate, migrate:rollback, migrate:reset, migrate:fresh, migrate:status, db:seed, db:wipe, route:list, about, key:generate, queue:work, queue:failed, queue:retry, queue:forget, schedule:run, schedule:work, schedule:list, openapi:export, codegen:types, codegen:client, codegen:routes, ssr:start, ssr:check, boost:mcp and openapi:serve (when you add apidocs.Command()). Destructive commands need --force in production. Add your own with vukem make:command (see Application lifecycle).
Running the binary directly works too: go run ./cmd/app migrate.
APP_KEY without the global CLI#
Docker images and CI runners usually ship only your compiled binary, not vukem. The app's own key:generate prints a new key and never touches .env; it also works before any APP_KEY exists, since it runs without booting the app:
./app key:generate # base64:...
export APP_KEY="$(./app key:generate)" # use it in the current shell
docker run --rm my-app key:generate # with ENTRYPOINT ["/app"]Only the key goes to stdout; errors and -h output go to stderr, so a typo never ends up inside APP_KEY. Store the printed value in your secret manager or deployment environment. vukem key:generate (global CLI) is the one that writes .env.
The built-in key:generate always wins over an app command registered with the same name, because it runs before the app is built.
vukem serve#
- Builds to a separate file and swaps it in after the old process stops, so it works on Windows where a running
.execannot be overwritten. - A failed build prints the compiler errors and keeps the previous version running.
- Views reload inside the app on every request in development; editing a template needs no rebuild.
- When a
vite.config.*exists,<pm> run devruns alongside (disable with--no-vite). - Package manager:
serve,buildandinstall:inertiause the one whose lockfile is in the project (bun.lock→ Bun,pnpm-lock.yaml→ pnpm,yarn.lock→ Yarn), else npm. No configuration needed: runbun installonce and the CLI follows.
Exit codes#
| Code | Meaning |
|---|---|
0 | Success |
1 | Failure (the error is printed) |
2 | Usage error: unknown command, missing argument, bad flag |
A delegated app command's exit code is passed through unchanged.