3.6 KiB
title, description
| title | description |
|---|---|
| Concepts | The mental model behind stanza — categories, vendoring, peers, and the manifest. |
A handful of ideas explain how stanza decides what to write and where. Once they click, the CLI's behavior is predictable.
Categories
Every module belongs to exactly one category. A category has two independent properties that govern how its modules behave:
- Cardinality —
one(single-choice) ormany(coexisting). - Home — where a module's output lands:
app,repo, orpackage.
| Category | Cardinality | Home |
|---|---|---|
framework |
one | app |
styling |
one | app |
db |
one | package |
orm |
one | package |
auth |
one | package |
tooling |
one | repo |
testing |
many | app |
A one category holds at most one module — adding a second fails until you
remove the first. A many category lets modules coexist (e.g. Vitest and
Playwright side by side).
Home decides placement. app modules wire your app shell (in apps/web/,
say). repo modules write config at the monorepo root. package modules install
into their own internal workspace package under packages/<dir>/, named
@<your-app>/<dir>, which your app consumes via workspace:*. db and orm
share a single packages/db/ so the ORM client sits next to the schema it
queries.
Vendoring
stanza copies a module's code into your repo verbatim. There's no shared runtime package — the generated files are ordinary source you can read, edit, and commit. That means upgrades never silently change your app's behavior, and you're never locked into stanza's abstractions.
Peers and adapters
Modules declare peers — the other categories they care about. When you add
a module, stanza reads your current selections and picks the adapter that
matches. Better Auth, for instance, peers on both framework and orm, so
adding it to a Next + Drizzle app produces different wiring than a TanStack Start
- Prisma app. You pick the module; stanza picks the right variant.
The manifest (stanza.json)
The stanza.json file at your repo root is the source of truth for what's
installed. It records your module selections per category and the regions —
the files and file-fragments — each module owns. add, remove, and list all
read it. Treat it as generated state: don't hand-edit it unless you're repairing
something deliberately.
Regions
A region is a claim on a file (or a section of one) by a specific module.
This is how stanza remove knows exactly what to delete and what to leave alone:
it sweeps only the regions the removed module owns. Because regions key on the
module, two modules can safely write disjoint parts of the same file — Vitest
owning the test script and Playwright owning test:e2e, for example, without
conflict.
Open registry
A registry is just static JSON: an index plus one file per module, each carrying
its templates, dependencies, env vars, and codemod invocations. The CLI ships
with a default registry, but you can point it anywhere — a URL or a local path —
with STANZA_REGISTRY. That's the hook for self-hosting your own modules or
pinning a fixture in CI.