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.
aspect init requires Aspect CLI v2026.25.11 or newer. See version pinning to lock a minimum version for your repo, or install to upgrade.Quickstart
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:
| Preset | What you get |
|---|---|
minimal | Bazel-only scaffold with no language rules — start from scratch. |
shell | Shell scripts (rules_shell) with shellcheck and shfmt. |
go | Go (rules_go + Gazelle). |
js | JavaScript / TypeScript (rules_js, rules_ts, pnpm workspaces). |
py | Python (aspect_rules_py + uv). |
java | Java (rules_java). |
kotlin | Kotlin (rules_kotlin). |
cpp | C/C++ (rules_cc). |
rust | Rust (rules_rust). |
ruby | Ruby (rules_ruby). |
scala | Scala (rules_scala). |
kitchen-sink | Every language preset above, wired into one workspace. Useful for exploring or for reproductions that span rulesets. |
--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 output directory, normalized to snake_case (hyphens become underscores). When the output directory is . or empty, the default is my_project.
--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).

