Quickstart
From nothing to a running application.
Create a project
npx @kreotic/kreogen@latest initYou are asked for a name and a package manager:
┌ Let's start a kreogen project!
│
◇ What is your project named?
│ my-app
│
◇ Which package manager would you like to use?
│ bun
│
◇ Prepared the project
│
└ Next steps: cd my-appThe CLI clones the template at its latest release tag, then makes it yours:
- Strips the template's own tooling —
apps/docs,packages/cli,.gitlab,ci,.claude, the changelog and the release config. None of it belongs to a project built from the template. - Swaps in your own
README.md,NOTICE,.gitlab-ci.yml,CLAUDE.mdandAGENTS.md, so you do not inherit kreogen's pipeline or kreogen's instructions to coding agents. - Converts to your package manager if you did not pick bun, rewriting
workspace:*ranges and bun-specific scripts and removingbun.lock. - Seeds
.envfiles from every.env.example. - Installs dependencies and makes an initial commit, in that order — git
first, because the root
preparescript runslefthook install, which fails outside a repository.
It also records where the project came from, in package.json:
"kreogen": { "version": "0.1.3", "repo": "..." }That stamp is what kreogen update reads later to work out
which changes you are missing.
Useful flags: --version <x.y.z> to pin a template version, --skip-install,
--disable-git, --scope <scope> to rename the @kreogen/* packages, and
-y to accept every default.
Start the infrastructure
cd my-app
bun run docker:upWhatever docker-compose.yml defines — Postgres, Redis, a mail sink, and
S3-compatible object storage if you kept the storage capability. Nothing to
sign up for and nothing installed natively. The script names no services on
purpose: which ones exist depends on what the project was generated with.
The mail sink is not decoration. Every transactional email in the auth flow is delivered to it when Resend is unconfigured, so sign-up needs it running — see Create an account below.
If a port was already taken the first time you ran this, the container was
created without a published port and comes back healthy on every later
up -d — still unreachable, and nothing in the output says so. The symptom is
a connection refused against a service Docker reports as running. Recreate it:
docker compose up -d --force-recreatedocker:up deliberately names no services, which is what makes it survive
capability removal, so it cannot special-case this for you.
Configure the two required values
Everything else is optional. These two are not.
packages/database/.env already points at the compose Postgres:
DATABASE_URL="postgresql://kreogen:kreogen@localhost:5432/kreogen"Generate a signing secret and put it in apps/app/.env.local:
bunx @better-auth/cli secretBETTER_AUTH_SECRET="<the generated value>"It must be at least 32 bytes, and byte-identical across every process that reads sessions.
Apply the schema
bun run migrateA baseline migration is committed, so this produces a working database on a fresh clone with no extra steps.
Optionally, populate it:
bun run db:seedTwo organizations with members, invitations and a few rows of the stub model — enough that the app lands on a populated screen rather than an empty state.
Run it
bun run dev| App | URL |
|---|---|
| App | localhost:3000 |
| Web | localhost:3001 |
| API | localhost:3002 |
| localhost:3003 | |
| Studio | localhost:3005 |
| Storybook | localhost:6006 |
Add --filter <app> to run just one: bun dev --filter app.
Create an account
Sign up at localhost:3000/sign-up. An organization is created for you automatically, and the session carries it — every authenticated page depends on that.
Email verification is required before an account can sign in. With no
RESEND_TOKEN set the message goes to the Mailpit container instead, so open
localhost:8025 and click the link there. See
transactional email for how the two transports are
chosen.
Sign-up therefore needs something listening on localhost:1025. If you skipped
bun run docker:up and have no Resend token, it fails with a named error
rather than creating an account nobody can confirm — which is the intended
outcome: verification used to be switched off whenever Resend was
unconfigured, and an unverified sign-up got a working session.
Add integrations as you need them
Nothing breaks while a key is absent — the corresponding client is undefined
and the feature is inactive. See environment
variables for the full list, and
the CMS setup if the project needs a blog or
legal pages.
Before you commit
bun run verifyLint, typecheck and test — the same thing CI runs.