Skip to content

CLI

The vukem CLI

Create projects, generate code, run the dev server, build binaries and run app commands such as migrate with one command.

Last updated:

Terminal
go install github.com/AlexGalhardo/vukem/cmd/vukem@latest
vukem list

vukem 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#

CommandDescription
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:billingStripe subscriptions (needs install:auth)
vukem make:proto <Name>, vukem codegen:rpc [--protoc]gRPC service skeleton and code generation
vukem down [--secret s], vukem upMaintenance mode: 503 with Retry-After; /<secret> sets a signed bypass cookie
vukem boost:installGuidelines, skills and the boost:mcp MCP server for AI coding agents
vukem install:apiAdd 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:rotateWrite a new APP_KEY to .env and move the old one to the front of APP_PREVIOUS_KEYS (key rotation)
vukem versionPrint 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#

CommandCreates
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, BillingProvider and SendReportsCommand work 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:

Terminal
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 command

vukem 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:

Terminal
./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 .exe cannot 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 dev runs alongside (disable with --no-vite).
  • Package manager: serve, build and install:inertia use the one whose lockfile is in the project (bun.lock → Bun, pnpm-lock.yaml → pnpm, yarn.lock → Yarn), else npm. No configuration needed: run bun install once and the CLI follows.

Exit codes#

CodeMeaning
0Success
1Failure (the error is printed)
2Usage error: unknown command, missing argument, bad flag

A delegated app command's exit code is passed through unchanged.