Movie resource: a module, an entity, a repository, and a controller.
You can build that resource in two ways: by running the CLI commands yourself, or by handing a single detailed prompt to your AI agent. Both produce the same result.
Prerequisites
The CLI runs on Bun. Install it first:Step 1: Install the CLI
1
Install the binary
Install the
talos binary with the official installer for your platform. It downloads the latest release, adds it to your PATH, creates the oo alias, and installs shell completions.- macOS / Linux
- Windows
2
Verify
Restart your shell, then confirm the CLI is available and check its version.
-h / --help and -v / --version are shortcuts for the help and version commands:3
Stay up to date
Upgrade to the latest release at any time.
upgrade checks GitHub and only reinstalls when a newer version is available:Step 2: Create the application
Scaffold a complete application withapp:create. Run it with no flags to be prompted for the name and destination:
app and shared modules, the entrypoint, the shared database, roles, Docker files, and config, then installs all dependencies. You are also offered optional CI/CD files for GitHub, GitLab, or Bitbucket.
During scaffolding the CLI runs git init and then asks “Install the commit-msg hook?” (enabled by default). Accepting it installs a git hook that keeps your commit messages consistent — see The commit message hook below. It then asks “Add skills for which assistants?”, a multiselect of coding assistants (Claude and Codex enabled by default) — see Step 3 for what those skills unlock.
Move into the project and start it:
app:start brings up the Docker services defined by the app module (when an api or microservice module is running), then runs every discovered api, microservice, spa, storybook, and swagger module concurrently. The api and microservice modules serve their entrypoint with hot reload, while spa, storybook, and swagger modules run their dev server.
The environment file is generated at
.env.yml in the project root. Edit it
to point at your database, Redis, and other services before starting.Start only part of the app
Pass--modules or --packages (aliases of one another) with a comma-separated list of module names to narrow what runs. Without either flag, every discovered module runs — regardless of type (api, microservice, spa, storybook, or swagger).
api or microservice (the types that depend on it); spa, storybook, and swagger modules don’t need it.
When you’re done, stop the app:
app:stop brings down the app module’s shared Docker stack with docker compose down. The running module processes (spa dev servers and hot-reloaded entrypoints) stop when you interrupt the app:start process with Ctrl+C. It accepts the same --modules/--packages name filter as app:start, but only to decide whether an api or microservice module is in scope — it always brings down the app module’s own Docker stack, not a named module’s individual docker-compose.yml:
The commit message hook
When you accept the “Install the commit-msg hook?” prompt duringapp:create, the CLI installs a native git commit-msg hook into your repository. It runs on every commit, validates the message, and aborts the commit with a list of errors if the message doesn’t conform. There is no husky or commitlint dependency — the check is built into the CLI and self-contained.
The hook is a small script at .git/hooks/commit-msg that simply delegates to the CLI:
What it enforces
Messages must follow the conventional-commit formattype(scope): Subject:
- Type — lower-case and one of
build,chore,ci,docs,feat,fix,perf,refactor,revert,style,test. - Scope — required, lower-case, and a valid scope (see below). Combine several with
,,/, or\. - Subject — non-empty, must start with an upper-case letter, and must not end with a period.
- Header — the whole
type(scope): Subjectline is limited to 100 characters. - Body — separated from the header by a blank line, with each line limited to 100 characters.
fixup! / squash! / amend! messages are always accepted so automated commits pass through.
Scopes are discovered automatically. Valid scopes are the literal
common plus the name of every directory under packages/* and modules/*
that contains a package.json. When you scaffold a new module like movie,
movie becomes a valid scope with no config to edit.Managing the hook
-
Install or reinstall it at any time (for example on a repo cloned without the hook):
-
Bypass it for a single commit with git’s built-in flag:
Project structure
app:create generates a Bun workspace organized around modules. Every module under modules/<name>/ owns its own controllers, services, repositories, entities, and config: a self-contained vertical slice of your domain.
Movie) becomes its own module alongside app and shared, registered automatically into AppModule.
Step 3: Build your first resource
With the app scaffolded, build theMovie domain. Choose the path that fits how you work: the CLI walks you through each artifact, while the AI prompt produces the whole slice in one pass.
- AI prompt
- CLI commands
Your project includes AI skills for every create command. Initialize them once, then give your agent a single prompt and it drives the Then copy this prompt into your agent:The agent scaffolds each artifact with the CLI, fills in the columns, methods, routes, and validation, and writes the tests, producing the same module structure shown in the CLI tab.
module:create, entity:create, repository:create, and controller:create skills for you.Skills for the assistants you selected during app:create are already scaffolded. If you skipped that prompt or need to add another assistant, run it directly:Resulting module structure
Either path produces the same module, a complete vertical slice for theMovie domain:
Next steps
CLI commands
Explore every generator: services, events, migrations, seeds, and more.
Controllers
Learn routing, validation, and role-based access in depth.
Entities
Model your data with TypeORM entities and the shared database.
Repositories
Query and persist data with the repository pattern.