Files
stanza/apps/web/content/docs/concepts.mdx
T
2026-05-22 18:37:24 -04:00

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:

  • Cardinalityone (single-choice) or many (coexisting).
  • Home — where a module's output lands: app, repo, or package.
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.

**Planned:** more categories are on the roadmap — `api`, `ai`, `payments`, `email` (single-choice) and `deploy` (coexisting). They aren't shipping yet, but the taxonomy is designed to absorb them without breaking existing projects. See the [module registry](/docs/registry) for the full roadmap.

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.