> ## Documentation Index
> Fetch the complete documentation index at: https://site.aspect.build/llms.txt
> Use this file to discover all available pages before exploring further.

# aspect init

> Scaffold a new Bazel workspace with aspect init: pick a language preset, choose a template source, and let tools/repin materialize the lockfiles.

`aspect init` scaffolds a new Bazel workspace from the [Aspect Workflows template](https://github.com/aspect-build/aspect-workflows-template). Pick a language preset, run one command, and you get a working `bazel build //...` repo with hermetic toolchains, [Gazelle](/docs/cli/tasks/gazelle)-generated BUILD files, [`aspect format`](/docs/cli/tasks/format), [`aspect lint`](/docs/cli/tasks/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

```shell theme={null}
aspect init [<project-name>] [flags]
```

The sole positional argument is the **project name, which also doubles as the output directory**:

* 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

```shell theme={null}
# Interactive: prompt for a project name, then pick a preset from a numbered list
aspect init && cd my-app

# Name the project upfront (scaffolds into ./my-app/)
aspect init my-app --preset js && cd my-app

# Scaffold into the current directory
aspect init . --preset go
```

### Interactive prompt

When you run `aspect init` on a TTY without a positional argument, the CLI prompts for the project name:

```text theme={null}
$ aspect init
Project name (or '.' for the current directory): my-app
```

Enter a bare name to scaffold into a new subdirectory of that name, or `.` 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:

```text theme={null}
$ aspect init --preset js < /dev/null
No project name given; pass a name (e.g. 'aspect init my-project') or '.' to scaffold into the current directory.
```

Pass an explicit project name (or `.`) in CI, scripts, and other non-interactive contexts:

```shell theme={null}
aspect init my-app --preset js
aspect init . --preset js   # current directory
```

After rendering, `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:

```text theme={null}
Done. Next steps:
  cd my-app
  aspect build //...
```

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

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.

```shell theme={null}
aspect init my-app --preset py
aspect init repro --preset kitchen-sink
```

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

```shell theme={null}
aspect init . --preset go --name my_service
```

### `--license <spdx>`

Whether to write a `LICENSE` file. Accepted values (case-sensitive):

* `Apache-2.0` — write the Apache 2.0 license.
* `none` — omit the `LICENSE` file. **Default.**

```shell theme={null}
aspect init my-app --preset js --license=Apache-2.0
```

The flag overrides the template's `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>`.

```shell theme={null}
# Default: latest release of aspect-build/aspect-workflows-template
aspect init my-app --preset js

# Track the template's main branch
aspect init my-app --preset js --template-ref=main

# Point at a fork or your own template
aspect init my-app --preset js --template=github:my-org/my-template
```

**`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.

```shell theme={null}
aspect init my-app --preset js --template=file:/path/to/checkout
aspect init my-app --preset js --template=file://./aspect-workflows-template
```

A missing or unknown scheme fails with a clear message (`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.

```shell theme={null}
aspect init my-app --preset py --skip-repin
cd my-app
./tools/repin   # run later, once your environment is ready
```

## 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:**

```shell theme={null}
aspect init my-app --preset js
cd my-app
aspect build //...
```

**Pin the template to a known good ref for a bug reproduction:**

```shell theme={null}
aspect init repro \
    --preset kitchen-sink \
    --template-ref=v2026.6.0
```

**Use a fork of the template:**

```shell theme={null}
aspect init my-app \
    --preset go \
    --template=github:my-org/aspect-workflows-template \
    --template-ref=main
```

**Scaffold offline from a local checkout:**

```shell theme={null}
git clone https://github.com/aspect-build/aspect-workflows-template
aspect init my-app \
    --preset py \
    --template=file:./aspect-workflows-template
```

## Related

* [Aspect CLI install](/docs/cli/install) — get the CLI on your machine.
* [Version pinning](/docs/cli/version-pinning) — lock a minimum CLI version for your repo.
* [Bazel + JavaScript](/docs/bazel/javascript) — what the `js` preset gives you.
* [Bazel + Python](/docs/bazel/python) — what the `py` preset gives you.
* [aspect-build/aspect-workflows-template](https://github.com/aspect-build/aspect-workflows-template) — the template source.
* [aspect-starters](https://github.com/aspect-starters) — each preset republished as a GitHub *template repository* (for the "Use this template" button).
