Project structure
Every file and package explained
After coldstart init, you get a Turborepo monorepo. What's inside depends on the platforms and features you selected. Here's a full-stack example (web + mobile + desktop + API + billing + i18n):
Conditional generation — only the platforms you select are generated. If you chose web + API only, there will be no apps/mobile/ or apps/desktop/ directories. Shared packages like db, env, and email are always generated when the API platform is included.
Root
Web app (apps/web/)
Scaffolded by create-next-app, then patched with auth, billing, theming, and i18n.
Key patterns:
[locale]/structure for i18n (e.g./en/dashboard,/fr/dashboard)(auth)/group for public auth pages,(app)/group for authenticated routesuseBilling()hook fetches from/billing/status— returnsisPremium,tier,credits<PremiumGate>wraps content that requires a paid plan — shows upgrade prompt if free
Mobile app (apps/mobile/)
Scaffolded by create-expo-app, then patched with Expo Router, Uniwind (Tailwind for RN), RevenueCat paywall, and i18n.
Key patterns:
- Expo Router with file-based routing (
app/directory) - Uniwind — Tailwind CSS classes in React Native via
classNameprop - HeroUI Native — component library styled with Uniwind
- RevenueCat — paywall UI and subscription management (
react-native-purchases) - EAS Build —
pnpm -F mobile build:dev,build:preview,build:prodfor device builds - Mobile does not use portless — it runs natively on device/simulator
Desktop app (apps/desktop/)
Uses Tauri 2 to wrap the web frontend in a native desktop shell. Shares the Next.js build output from apps/web/.
Key patterns:
- Shares the web frontend —
tauri devserves fromhttp://localhost:3000,tauri buildusesapps/web/out/ - Native installers —
.dmg(macOS),.msi(Windows),.AppImage/.deb(Linux) viatauri build - Security — CSP configured in
tauri.conf.jsonto restrict script/style sources - Rust plugins —
tauri-plugin-shellpre-configured, add more inCargo.toml - Desktop requires the Rust toolchain — build with
pnpm -F desktop build:desktop
API (apps/api/)
Generated from scratch with Hono, Better Auth, Drizzle, and typed middleware.
Key patterns:
OpenAPIHono<AppEnv>— typed context,c.get("user")returns{ id, email, name }- Auth routes at
/api/auth/*forwarded to Better Auth - Billing middleware queries
userBillingtable — no unsafe casts - Webhooks verify signatures and write real DB operations
- OpenAPI docs at
/openapi
Shared packages
packages/db/ — Drizzle ORM with Neon PostgreSQL
pnpm -F @my-saas/db db:generate # Generate migrations
pnpm -F @my-saas/db db:migrate # Run migrations
pnpm -F @my-saas/db db:studio # Open Drizzle Studiopackages/env/ — Zod-validated environment variables
Three entry points, one per platform:
./server— DATABASE_URL, BETTER_AUTH_SECRET, Stripe/Polar keys./web— NEXT_PUBLIC_API_URL, NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY./native— EXPO_PUBLIC_API_URL, RevenueCat keys
If any required variable is missing, the app fails at startup — not at the first request.
packages/email/ — React Email templates
Three templates pre-built:
verification.tsx— email verification linkreset-password.tsx— password reset linkwelcome.tsx— welcome email after signup
Preview with: pnpm -F @my-saas/email preview (runs on port 3333)
packages/config/ — shared TypeScript config
tsconfig.base.json extended by all apps and packages. Strict mode, ES2022 target, bundler module resolution.
Scripts
| Script | Purpose |
|---|---|
scripts/install-skills.sh | Installs 5-40 Claude Code skills tailored to your stack (React, Tailwind, Hono, Drizzle, etc.) |
scripts/setup-mcps.sh | Configures MCP servers in .claude/settings.json (Neon, Vercel, Polar, Resend, etc.) |
scripts/release.sh | EAS build + submit for mobile app (production profile, iOS + Android) |
scripts/release-local.sh | Local EAS build + submit — useful for testing before CI |
release.sh and release-local.sh are only generated when the mobile platform is selected.
CI/CD workflows
Three GitHub Actions workflows are generated based on your platform selection:
Always generated. Runs on every push and PR to main:
pnpm install --frozen-lockfilepnpm lint(Biome)pnpm check-types(TypeScript)pnpm test(Vitest)pnpm build(if web platform)
If the API platform is selected, a PostgreSQL service container is provisioned for the tests.
Generated when web is selected. Placeholder for Vercel deployment:
Vercel auto-deploys from git — this workflow is a hook for custom pre/post-deploy logic. Configure via the Vercel dashboard or the Vercel MCP server.
Generated when desktop is selected. Triggered on version tags (v*):
- Builds on macOS, Linux, and Windows in parallel
- Uses
dtolnay/rust-toolchainandswatinem/rust-cachefor fast Rust compilation - Runs
tauri-apps/tauri-actionto produce native installers - Uploads artifacts as GitHub Release assets
Key files
| File | Purpose |
|---|---|
CLAUDE.md | AI context: stack, domain guidelines, conventions, commands, how-to guides, MCP servers |
.coldstart.json | Every option you selected — use with coldstart replay to reproduce |
.claude/settings.json | MCP servers (Neon, Vercel, Polar, RevenueCat, Resend, Expo) |
turbo.json | Build pipeline: dev, build, check-types, lint, test |
biome.json | Linter/formatter: tabs, 100 chars, double quotes, semicolons |
lefthook.yml | Git hooks: pre-commit (lint), pre-push (check-types + test) |
docker-compose.yml | Local PostgreSQL for development |