How the template works
How the template is filtered
Section titled “How the template is filtered”template.json at the repository root defines which paths belong to which client stack:
| Key | Meaning |
|---|---|
placeholder |
Placeholder project name used in the template (acme, Acme). Its uppercase form (ACME) is also replaced |
defaultTheme |
Theme whose color ramps are stored in design/tokens/palette.json in the template repository |
exclude |
Repository paths that stay in this template repository and are never embedded in the binary |
common |
Paths included in every generated project |
shared |
Named groups of paths shared by multiple targets, such as js-workspace |
targets |
Per-stack definitions: id, title, stack, platforms, paths, requires (names of shared groups), outputs (kinds of generated token files the stack reads, matching the keys of design/build.json), format (the command that formats its code, if any), and run (commands shown after create) |
Shared configuration files use conditional comment blocks to include lines only when specific targets are selected. A comment line @if <target ids> opens a block and @endif closes it:
[tools]node = "26.13.1"# @if web-react mobile-react-nativepnpm = "12.19.0"# @endif# @if desktop-gpuirust = { version = "1.99.1", components = "rustfmt,clippy" }# @endif- A conditional block is kept when any of its listed targets is selected. The marker lines themselves are stripped from the generated project.
- Blocks can be nested and can wrap individual elements inside multi-line arrays.
- Each marker must occupy its own full comment line.
#,//,<!-- -->, and/* */comment styles are supported;cli/src/markers.rslists them. @if templatemarks lines needed only in this repository, such as thecliworkspace member and the CLI’s CI job.templateis never selected in generated projects.- A marker that references an unknown target ID is an error, and the test suite renders every combination of targets so a typo cannot silently drop a block.
Within this repository, marker lines act as ordinary comments so every block remains active.
Files under cli/overlay are written over the generated project root with the same conditional block filtering and placeholder renaming. That is where the generated project’s README.md, AGENTS.md, and CLAUDE.md come from.
design/components.json is cut down like design/build.json: a project gets the components its clients have, each with the source files of those clients only.
Binary files (detected by a NUL byte within the first 8 KB) are copied verbatim.
Adding a client stack
Section titled “Adding a client stack”- Add the client code, using the
acmeplaceholder for names in both file contents and file paths. - If the stack consumes a new format of generated token file, add an emitter to
tools/design-buildand an entry todesign/build.json. - Add a target entry to
template.json: itspaths, thesharedgroups itrequires, theoutputsit reads, and itsruncommands. Include aformatcommand if the stack has a formatter enforced bymise run check. - Wrap any stack-specific additions to the shared root files (
mise.toml,.github/workflows/ci.yml,.gitignore,.gitattributes,Cargo.toml,pnpm-workspace.yaml,cli/overlay/README.md) in@if <id>blocks. - List the stack’s components in
design/components.json, with the source file and the symbol of each. - Run
cargo test -p xds. The tests fail if any repository file belongs to no target, shared group,common, orexclude; if any conditional marker is unbalanced or references an unknown target; or ifmise.tomlorCargo.tomlis not valid TOML for any combination of targets. Add the new target’s expectations toshared_files_are_valid_for_every_combination_of_targetsincli/src/tests.rs.
No Rust code changes are needed when adding a stack that follows this structure.