Build your own pack
A pack is a folder with a manifest.json and a files/ directory. The manifest says where each file goes and how it
wires into the app. That's the whole format. Nothing gets compiled, nothing gets published to us, and no code of yours
runs on anyone else's machine.
Packs you build are community packs. They install through their own command, hype-stack community, so it's always
obvious when a project is pulling in code that didn't come from the Hype Stack catalog.
Start one
npx @hype-stack/cli community init pack-analyticsYou get a manifest, a files/ tree for the surfaces you picked, and a README. It validates as-is, so you can install it
immediately and then fill it in.
The loop
Write code under files/, declare it in the manifest, then:
npx @hype-stack/cli community validateRun it as often as you like. It checks the same things the installer does, plus the ones that fail silently: a file
sitting in files/ that no manifest entry declares never gets copied, so the pack installs "successfully" and the
feature is missing a piece.
Install it into a real project to try it:
npx @hype-stack/cli community add ../pack-analyticsRe-run it with --force after each change to overwrite what you installed last time.
Files and where they land
Every entry in files has a source (relative to the pack) and a target:
{
"source": "files/frontend/src/features/analytics",
"target": "{{frontend.features}}/analytics",
"strategy": "create"
}Targets are path templates, not literal paths. {{frontend.features}} resolves against the project's own
stack.json, so your pack lands correctly in a project whose directories are laid out differently from yours. The apps
you can address are backend, frontend, admin, mobile, extension, and enums.
A source can be a single file or a whole directory. A directory copies everything under it.
Strategies
| Strategy | What it does |
|---|---|
create | Writes the file, and asks before overwriting an existing one. The default |
skip-if-exists | Writes it only if nothing is there. Never overwrites, never asks |
override | Always wins. For files the pack cannot function without |
merge | Splices the source into the target at a marker string |
merge-json | Deep-merges a JSON source into an existing JSON target |
Slots
Tag a file with a slot (admin, mobile, extension) and it only installs when the project actually ships that app.
Files with no slot always install.
Wiring into the app
Copying files isn't usually enough: a backend route has to get registered, a nav entry has to appear in the sidebar. You declare those in the manifest and the CLI patches the right file at install time. The full field list is in the manifest reference.
Database models
Ship .prisma files, never migrations.
Prisma's multi-file schema means a pack contributes models by dropping a file into the schema directory:
{
"source": "files/backend/prisma/schema/analytics.prisma",
"target": "{{backend.prisma}}/schema/analytics.prisma",
"strategy": "create"
}The CLI notices and offers to run prisma migrate dev in the project, which generates a migration against that
project's own history. A migration you ship instead would diverge the first time anyone ran migrate dev themselves.
That schema directory is a shared namespace: your models sit next to the starter's and every other pack's. Before writing anything, the CLI checks whether a model, enum, type, or view you declare is already taken, and refuses with both filenames if it is. Prefix your models if there's any chance of a clash.
Dependencies
dependencies names packs that must be installed first. If your code imports from a starter, say so:
"dependencies": ["starter-saas-workos"]npm packages go in dependencies_npm, per app:
"dependencies_npm": { "frontend": { "recharts": "^2.15.0" } }Publish it
There's no registry to submit to. Push the folder to a repository or publish it to npm, and people install it directly:
npx @hype-stack/cli community add github:you/pack-analytics#v1.0.0
npx @hype-stack/cli community add npm:@you/pack-analyticsBoth are pinned the same way anything else is: a git ref or an npm version. The CLI records where each pack came from
in the project's stack.json, so anyone can run community list later and see whose code is in there.
Editor support
Point $schema at the published schema and your editor will complete and check the manifest as you type. community init does this for you:
{
"$schema": "https://www.hype-stack.dev/schema/pack-manifest-v1.json"
}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!
