A minimal, production-verified starter for full-stack apps on this stack:
- Monorepo — bun workspaces (
apps/*,packages/*), Biome for lint/format. - Web (
apps/web) — TanStack Start on Cloudflare Workers (@cloudflare/vite-plugin), Tailwind v4 + shadcn/ui, reads via@convex-dev/react-query. - Backend (
packages/api) — Convex (dev + prod deployments). - Auth — WorkOS AuthKit hosted login (
@workos/authkit-tanstack-react-start). - CI/CD — GitHub Actions: PR checks + push-to-deploy (
dev→ dev env,main→ prod). - Mobile —
apps/mobile/is a README-only placeholder for a future Expo app.
This is a runnable app, not a {{mustache}} skeleton: / landing, WorkOS
sign-in, and a placeholder signed-in /home route that reads the current user
(Hello, {name}) — demonstrating the authed read path end-to-end. Build your app
by replacing /home.
The template is versioned (see VERSION +
TEMPLATE_CHANGELOG.md) so improvements can flow from the
template into projects created from it.
.
├── apps/
│ ├── web/ # TanStack Start + Cloudflare Workers
│ └── mobile/ # placeholder for Expo (README only)
├── packages/
│ └── api/ # Convex schema + functions + generated client (@stack/api)
├── docs/
│ ├── SETUP.md # external setup: Cloudflare, Convex, WorkOS, GitHub, secrets
│ └── adr/ # architecture decision records
├── .github/workflows/ # ci.yml (checks) + deploy.yml (push-to-deploy)
├── VERSION # template version this tree is at
└── TEMPLATE_CHANGELOG.md # what changed between template versions
-
On GitHub, click Use this template → create your repo (or clone
dendotai/stackand re-pointorigin). -
Rename the placeholders. The init script takes named flags; the only required one is
--name, given as the domain with dots→dashes (the repo-naming convention, e.g.widget-io,acme-com). Everything else is derived from it:bun scripts/init.mjs --name acme-com # → @acme-com scope, acme.com / dev.acme.com domains, # acme-com.internal dev host, acme-com{,-dev,-prod} worker names bun scripts/init.mjs --name acme-com --dry-run # preview, write nothing
--nameis the single token that flows everywhere (repo/package/scope/worker names). Override any derived value with its own flag — e.g.--scope acmefor a shorter@acme/api, or--domain/--dev-domain/--host. The script rewrites the distinctive tokens and copies the*.exampleenv files into place. It leaves display strings (the landing<h1>, the page<title>, this README) —grep -rn '\bstack\b'and edit by taste.Prefer to do it by hand? The full flag list + token mapping is documented at the top of
scripts/init.mjs. -
bun install. -
Provision the external services and wire secrets — follow docs/SETUP.md.
-
Fill the
.dev.vars/.env.localfiles the script created, thencd packages/api && bunx convex devonce to link your dev deployment.
bun run dev # web (:3000) + convex, in parallel — needs the `muxa` runner (see SETUP)
bun run check # lint + typecheck + test (mirrors CI)
bun run build # build every workspaceEach workspace's scripts are documented in its own README / package.json.
Push to dev → deploys to the dev environment; push to main → prod. The
pipeline (.github/workflows/deploy.yml) deploys Convex first, then builds and
deploys the Worker, reading per-environment GitHub Variables and Secrets.
See docs/SETUP.md for the one-time provisioning.
The template evolves; pull its improvements without a hard fork:
- Check your project's current template version in
VERSION. - Read
TEMPLATE_CHANGELOG.mdin the latest template for every entry newer than that version. Each entry says what changed and, when it isn't a clean file copy, how to apply it. - Apply those changes to your project (this is designed to be agent-driven — point your agent at the two changelogs and the template repo).
- Bump your project's
VERSIONto the version you applied up to.
Because the template stays a real, runnable app, you can also just diff specific
files against dendotai/stack when you want a single improvement.