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
npx @hype-stack/cli composeThis opens an interactive picker. Free packs install without an account. Paid packs you own are marked as owned; paid packs you don't own yet show their price and a lock.
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:
npx @hype-stack/cli compose --packs starter-saas-workos,pack-teams,pack-projects --yesAdmin 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:
npx @hype-stack/cli compose --packs layout-glass@frontend,layout-basic@adminTheme, radius, and mode
compose takes the same look-and-feel flags as create, so one command reproduces a stack you built
in the live preview:
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. |
Run in a directory with no project and compose scaffolds one first, passing these values straight into the create
wizard. In an existing project it only rewrites what you named: a plain compose never touches your styles.css.
What happens during install
- Dependency resolution - any packs your selection depends on are pulled in and ordered automatically
- Validation - the whole plan is checked before a single file is written, so a bad install never leaves a half-modified project
- File install - schema, backend routes, and frontend pages are copied into the right places, in dependency order
- NPM install - every pack's dependencies are installed in one pass per workspace
- Codegen - you're prompted to run
prisma generateand a migration for any new models - Config update -
stack.jsonrecords each installed pack
Translations
Packs ship no hardcoded UI copy. Every string a pack renders comes from a
Paraglide 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.
// 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:
npx @hype-stack/cli loginThat stores a token that expires after 90 days. For CI, create an API key on the API keys page and expose it as an env var. No flag, no secret in your shell history:
HYPE_STACK_TOKEN=hsk_ci_xxx npx @hype-stack/cli compose --packs pack-billing-stripe --yesAPI keys are revocable and shown in full only once, so a leaked key can be killed without touching your license.
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, which fills in the env
vars your new packs need. You can also run it yourself later.
Every purchase and sponsorship funds my 8+ years of work on open source given freely to the community. It keeps the lights on, funds new packs, and keeps the ecosystem alive. Even a small tier means a lot. Thank you!
