Source: https://www.hype-stack.dev/docs/cli/add-pack

# Compose Your Stack

Packs are self-contained feature modules you install into an existing project. Each pack brings its own schema, routes,
UI components, and migrations. The `compose` command lets you pick several at once and installs them in the right order.

## Usage

```bash
npx @hype-stack/cli compose
```

This opens an interactive picker that walks the three categories in order: one starter, one layout, then any feature
packs. Billing is a one-of group, since a project takes a single provider. Installing anything needs a Hype Stack
account, free packs included; `compose` opens the browser to sign in if you aren't. Free packs stay free. Paid packs you
own are marked as owned; paid packs you don't own yet show their price and a lock.

Run it in a directory with no project and `compose` scaffolds one first with the [`create`](/docs/cli) wizard, then
installs your picks into it.

**Use the wizard**

You rarely need to hand-build the full command. Run `npx @hype-stack/cli compose` with no flags and the wizard walks you
through picking packs, resolving dependencies, and handling licenses. Reach for the flags below only in CI or scripts
where prompts aren't an option.

For CI or scripts, pass the packs directly:

```bash
npx @hype-stack/cli compose --packs starter-saas-workos,pack-teams,pack-projects --yes
```

## Pack families

Three groups of packs are interchangeable variants of one family: starters (`starter-saas`), layouts (`layout`), and
billing (`pack-billing`). A family has one slot in a project. Ask for a second variant and `compose` refuses, with one
exception: swapping a starter for one that provides more (the free `starter-auth-betterauth` to
`starter-saas-betterauth` or `starter-saas-workos`) is an upgrade. The CLI replaces the files both starters ship,
removes the ones only the old one had, and re-applies your layout. Your own files are never touched.

Packs depend on families, not on one engine. A calendar pack that needs a starter says `starter-saas`, and whichever
starter your project has satisfies it.

## Admin layout

When your project has an admin app, the picker asks once whether to copy the frontend layout for it, defaulting to yes.
Say no and you get the full admin layout list, limited to the layouts the admin shell can actually render. To pin both
sides yourself, suffix the pack with the shell it targets:

```bash
npx @hype-stack/cli compose --packs layout-glass@frontend,layout-basic@admin
```

## Theme, radius, and mode

`compose` takes the same look-and-feel flags as [`create`](/docs/cli/index), so one command reproduces a stack you built
in the live preview:

```bash
npx @hype-stack/cli compose --packs starter-saas-workos,layout-basic@frontend,pack-teams --theme ocean --radius 0.75rem --mode dark
```

| Flag                         | What it does                                            |
| ---------------------------- | ------------------------------------------------------- |
| `-t, --theme <theme>`        | Frontend color theme.                                   |
| `--admin-theme <theme>`      | Admin color theme. Defaults to `--theme`.               |
| `--mobile-theme <theme>`     | Mobile app color theme. Defaults to `--theme`.          |
| `--extension-theme <theme>`  | Extension color theme. Defaults to `--theme`.           |
| `--radius <value>`           | Frontend corner radius as a CSS length, e.g. `0.75rem`. |
| `--admin-radius <value>`     | Admin corner radius. Defaults to `--radius`.            |
| `--mobile-radius <value>`    | Mobile app corner radius. Defaults to `--radius`.       |
| `--extension-radius <value>` | Extension corner radius. Defaults to `--radius`.        |
| `--mode <light\|dark>`       | Color mode the app boots in.                            |

In an existing project `compose` only rewrites what you named: a plain `compose` never touches your `styles.css`.

### All flags

| Flag                   | What it does                                                                                    |
| ---------------------- | ----------------------------------------------------------------------------------------------- |
| `--packs <a,b,c>`      | Install these packs without the picker. Layouts take an `@frontend` or `@admin` suffix.         |
| `--community <source>` | Also install a [community pack](/docs/packs-templates/build-your-own). Repeatable.              |
| `--force`              | Overwrite files that already exist. Without it you are asked per file, and `--yes` keeps yours. |
| `-y, --yes`            | Skip confirmations. Keeps existing files, answers yes to migrations.                            |
| `--cwd <path>`         | Run against a different working directory.                                                      |

## What happens during install

1. **Dependency resolution** - any packs your selection depends on are pulled in and ordered automatically, with family
   dependencies pinned to the variant your project already has
2. **Capability check** - a pack that needs organizations or invitations is refused by name if no installed or selected
   starter provides them
3. **License check** - paid packs are authorized against your license before a byte is downloaded. If something is
   locked, the CLI drops what you cannot install and shows where to buy it
4. **Validation** - the whole plan is checked before a single file is written, so a bad install never leaves a
   half-modified project. Prisma models that clash with one already in your schema abort with both file names
5. **File install** - schema, backend routes, and frontend pages are copied into the right places, in dependency order,
   then codemods register routes, nav entries, settings tabs, jobs, and permissions
6. **npm install** - every pack's dependencies are added in one pass per workspace
7. **Secrets** - env variables a pack marks as generated (an auth secret, a cookie password) are rolled for you
8. **Migrations** - `prisma generate` always runs. If the packs added models, you are asked to run `prisma migrate dev`
   now. Installs that add no models do not ask
9. **Config update** - `stack.json` records each installed pack and where it came from

## Translations

Packs ship no hardcoded UI copy. Every string a pack renders comes from a
[Paraglide](https://inlang.com/m/gerre34r/library-inlang-paraglideJs) message catalog, and install merges each pack's
messages into your app's `messages/en.json` instead of overwriting it. Two packs can contribute to the same file, and
re-running `compose` produces no diff for messages you already have.

```json
// apps/frontend/messages/en.json, after installing teams and billing
{
  "$schema": "https://inlang.com/schema/inlang-message-format",
  "app_title": "Acme",
  "teams_page_title": "Teams",
  "billing_upgrade_cta": "Upgrade"
}
```

Sidebar entries and settings tabs are merged the same way, so a pack's nav label is translatable too rather than being
frozen into `nav.constants.ts`.

To add a language, add its code to `locales` in `project.inlang/settings.json`, drop a `messages/<locale>.json` next to
the English one, and translate the values. Anything you have not translated yet falls back to English. Only `en.json` is
merged on install, so your other locale files are never touched. Rewording a pack's English in `en.json` is fine, just
know that re-installing that pack puts its own wording back.

## Access tokens

Paid packs need access. Log in once with your browser:

```bash
npx @hype-stack/cli login
```

That stores a token that expires after 90 days. For CI, create an API key on the [API keys](/api-keys) page and expose
it as an env var. No flag, no secret in your shell history:

```bash
HYPE_STACK_TOKEN=hsk_ci_xxx npx @hype-stack/cli compose --packs pack-billing-stripe --yes
```

API keys are revocable and shown in full only once, so a leaked key can be killed without touching your license.

## Community packs

Packs you wrote, or someone else published outside our catalog, install through the same pipeline from a folder, a git
repo, an npm package, or a registry namespace:

```bash
npx @hype-stack/cli community add ../pack-analytics
npx @hype-stack/cli compose --packs pack-teams --community github:you/pack-analytics#v1.0.0
```

Anything that is not a local folder gets a confirmation that defaults to no. See
[Build your own pack](/docs/packs-templates/build-your-own).

## Removing a pack

Packs are designed to be ejected. Once installed, the code lives in your project. Delete the files and revert the schema
changes to remove a pack. The CLI doesn't automate removal, since most teams customize pack code after installing it.

## Next

At the end of a `compose` run the CLI offers to walk you through [`onboard`](/docs/cli/onboard), which fills in the env
vars your new packs need. You can also run it yourself later.
