aspect init scaffolds a new Bazel workspace from the Aspect Workflows template. Pick a language preset, run one command, and you get a working bazel build //... repo with hermetic toolchains, Gazelle-generated BUILD files, aspect format, aspect lint, and a curated bazelrc.
Use it when you’re starting a new project, prototyping how a language ruleset fits together, or producing a minimal reproduction for a bug report. The command is native to the CLI — there is no external scaffold binary to install.
Synopsis
- A bare name (
aspect init my-app) scaffolds into a new./my-app/subdirectory. .(aspect init .) targets the current directory.- Omitting the argument on a TTY prompts interactively for the name. Off a TTY (CI, scripts, pipes) the argument is required — the command exits with a hint rather than silently scaffolding into the current directory.
Quickstart
Interactive prompt
When you runaspect init on a TTY without a positional argument, the CLI prompts for the project name:
. to scaffold into the current directory. Submitting an empty line exits with a non-zero status — aspect init never falls back to the current directory by default.
Non-interactive use
Off a TTY, the positional argument is required:.) in CI, scripts, and other non-interactive contexts:
aspect init runs tools/repin inside the new workspace to materialize the language lockfiles the template ships as placeholders. The final output points you at the next steps:
Workspace guard
aspect init refuses to scaffold into a directory that already looks like a Bazel workspace. If the target contains a MODULE.bazel, WORKSPACE, WORKSPACE.bazel, or WORKSPACE.bzlmod file, the command exits with a message and does nothing — so running aspect init from inside an existing repo is safe.
To start a fresh project, point aspect init at a new directory (aspect init my-app) or cd into an empty one and run aspect init ..
Presets
A preset selects which language(s) and tools the scaffolded workspace includes. Pass--preset <name> to skip the interactive picker:
When you omit
--preset, the CLI prints a numbered list and reads your choice from the terminal. Non-TTY invocations (CI, scripts, pipes) must pass --preset=<name> explicitly — the command fails fast otherwise.
Flags
--preset <name>
The preset to scaffold. Omit for the interactive picker. An unknown name fails with the list of valid presets.
--name <project_name>
Override the project name baked into the generated files (module name in MODULE.bazel, package names, etc.). Defaults to the basename of the positional argument, normalized to snake_case (hyphens become underscores) — so aspect init my-app produces a module named my_app. When the positional is . (current directory), the default falls back to my_project; use --name to override it.
--license <spdx>
Whether to write a LICENSE file. Accepted values (case-sensitive):
Apache-2.0— write the Apache 2.0 license.none— omit theLICENSEfile. Default.
license feature gate; the default none keeps the scaffold permissive about what you add later.
--template <scheme>:<value>
Where to fetch the template tree. The value is a scheme-prefixed locator so new source kinds can be added without changing the flag surface. Two schemes are built in:
github:<owner>/<repo> (default: github:aspect-build/aspect-workflows-template)
Downloads the template archive from GitHub. By default, aspect init resolves the repo’s latest published release — so an installed CLI picks up template updates without a CLI upgrade. Override the ref with --template-ref <branch|tag|commit>.
file:<dir> (also file://<dir> URI form)
Use a local checkout of a template repo. --template-ref is ignored — the directory is read as-is. This is the form to use when you’re developing the template itself or running fully offline.
supported: github:, file:).
--template-ref <branch|tag|commit>
Override the ref resolved for github: templates. Accepts any value the GitHub archive/<ref>.tar.gz endpoint accepts — a branch (main), a tag (v1.2.3), or a commit SHA. Ignored when --template uses the file: scheme.
--skip-repin
Skip the post-render tools/repin step. Use this when you don’t have the lockfile toolchain (uv, pnpm, etc.) installed on your machine yet, or when you want to inspect the generated tree before lockfiles are materialized.
The post-render tools/repin step
The Aspect Workflows template ships language lockfiles (uv.lock, pnpm-lock.yaml, Cargo.lock, etc.) as placeholders. After rendering, aspect init runs the generated tools/repin script inside the new workspace to populate them so the project is immediately buildable.
tools/repin is a regular shell script in the scaffolded tools/ directory; you can run it again at any time after changing dependencies. Pass --skip-repin to opt out of the automatic run — for example when bootstrapping in an environment that doesn’t have the relevant package manager installed yet.
If the scaffold doesn’t contain tools/repin (the minimal preset, for example), the step is skipped silently.
Examples
Start a JS/TS project, then build it:Related
- Aspect CLI install — get the CLI on your machine.
- Version pinning — lock a minimum CLI version for your repo.
- Bazel + JavaScript — what the
jspreset gives you. - Bazel + Python — what the
pypreset gives you. - aspect-build/aspect-workflows-template — the template source.
- aspect-starters — each preset republished as a GitHub template repository (for the “Use this template” button).

