Project Structure
Understanding the structure of projects created by Better-T-Stack CLI
Overview
Better-T-Stack CLI scaffolds a monorepo with apps/* and packages/*. packages/config is always present; other packages and apps appear based on your choices (frontend, backend, API, database/ORM, auth, addons, runtime, deploy). This page mirrors what the CLI actually writes.
Root layout
At the repository root you will see:
Notes:
bts.jsonclets the CLI detect and enhance your project later; keep it if you plan to usecreate-better-t-stack add.turbo.jsonexists only if you picked the Turborepo addon.pnpm-workspace.yaml,bunfig.toml, and.npmrcare added based on the package manager you choose.packages/infrais created only when Cloudflare deployment is enabled.
Monorepo structure by backend
Server backends (hono, express, fastify, elysia)
Notes:
apps/docsis created only with the Starlight addon.apps/fumadocsis created only with the Fumadocs addon.
Self backend (fullstack)
When --backend self is used, API routes live inside apps/web (no apps/server).
Convex backend
Frontend Structure (apps/web)
The structure varies by framework. Items marked "(auth)" or "(API)" appear only when those options are enabled.
React with TanStack Router
Next.js
Notes:
- If you choose
--backend selfwith Next.js, TanStack Start, Nuxt, or Astro, API routes live insideapps/web(noapps/server). - (auth) adds
src/app/login/*andsrc/app/dashboard/*plus sign-in components.
Backend Structure (apps/server)
The server structure depends on your backend choice:
Hono backend
Express / Fastify / Elysia
Workers runtime (optional)
When runtime=workers, the server targets Cloudflare Workers. If you also choose Cloudflare deployment, you'll get packages/infra/alchemy.run.ts and related infra files.
API and auth scaffolding (conditional):
- API=trpc:
src/lib/trpc.ts,src/lib/context.ts - API=orpc:
src/lib/orpc.ts,src/lib/context.ts - Auth:
src/lib/auth.ts
Database Configuration
Added only when you selected a database and ORM:
Drizzle ORM
Prisma ORM
Mongoose (MongoDB)
Auth + DB
If you selected auth, additional files are added for your ORM:
- Drizzle:
src/db/schema/auth.ts - Prisma:
prisma/schema/auth.prisma - Mongoose:
src/db/models/auth.model.ts
Docker compose (optional)
If dbSetup=docker, a docker-compose.yml is added in apps/server/ for your database.
Native App Structure (apps/native)
Created only when you include React Native (NativeWind or Unistyles):
If an API is selected, a client utility is added:
- API=trpc:
utils/trpc.ts - API=orpc:
utils/orpc.ts
Documentation Structure
Starlight (apps/docs)
Fumadocs (apps/fumadocs)
Fumadocs is generated by create-fumadocs-app inside apps/fumadocs. The exact structure depends on the template you choose (MDX vs static).
Configuration Files
Better-T-Stack Config (bts.jsonc)
{
"$schema": "https://r2.better-t-stack.dev/schema.json",
"version": "<cli-version>",
"createdAt": "<timestamp>",
"database": "<none|sqlite|postgres|mysql|mongodb>",
"orm": "<none|drizzle|prisma|mongoose>",
"backend": "<none|hono|express|fastify|elysia|convex|self>",
"runtime": "<bun|node|workers|none>",
"frontend": ["<tanstack-router|react-router|tanstack-start|next|nuxt|svelte|solid|astro|native-bare|native-uniwind|native-unistyles|none>"] ,
"addons": ["<pwa|tauri|starlight|fumadocs|biome|lefthook|husky|ruler|mcp|turborepo|ultracite|oxlint|opentui|wxt|skills|none>"] ,
"examples": ["<ai|todo|none>"] ,
"auth": <"better-auth"|"clerk"|"none">,
"packageManager": "<bun|pnpm|npm>",
"dbSetup": "<turso|neon|prisma-postgres|planetscale|mongodb-atlas|supabase|d1|docker|none>",
"api": "<none|trpc|orpc>",
"webDeploy": "<cloudflare|none>",
"serverDeploy": "<cloudflare|none>"
}Turborepo Config (turbo.json)
Generated only if you chose the Turborepo addon.
{
"$schema": "https://turbo.build/schema.json",
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", ".next/**"]
},
"dev": {
"cache": false,
"persistent": true
}
}
}Shared packages
Better-T-Stack always creates packages/config. Other packages are added based on your selections:
packages/env: when any frontend is selected or the backend is notnonepackages/api: when--apiis notnone(non-Convex)packages/auth: when--authis notnone(non-Convex)packages/db: when both--databaseand--ormare selected (non-Convex)packages/backend: Convex backend onlypackages/infra: Cloudflare deployment only
Development Scripts
Scripts are adjusted based on your package manager and whether the Turborepo addon is selected.
With Turborepo:
{
"scripts": {
"dev": "turbo dev",
"build": "turbo build",
"check-types": "turbo check-types",
"dev:web": "turbo -F web dev",
"dev:server": "turbo -F server dev",
"db:push": "turbo -F server db:push",
"db:studio": "turbo -F server db:studio"
}
}Without Turborepo (example for Bun):
{
"scripts": {
"dev": "bun run --filter '*' dev",
"build": "bun run --filter '*' build",
"check-types": "bun run --filter '*' check-types",
"dev:web": "bun run --filter web dev",
"dev:server": "bun run --filter server dev"
}
}Notes:
- Convex adds
dev:setupfor initial backend configuration. - Database scripts (
db:*) are added only when a database + ORM are selected (Drizzle/Prisma). D1 + Cloudflare omitsdb:studio.
Key Details
- Monorepo:
apps/*andpackages/*are created only when relevant (exceptpackages/config, which is always present) - React web base: shadcn/ui primitives,
components.json, common utilities - API clients:
src/utils/trpc.tsorsrc/utils/orpc.tsadded to web/native when selected - Auth: Adds authentication setup based on provider:
better-auth:src/lib/auth.tson server and login/dashboard pages on web appclerk: Clerk provider setup and authentication components
- ORM/DB: Drizzle/Prisma/Mongoose files added only when selected
- Extras:
pnpm-workspace.yaml,bunfig.toml, or.npmrcadded based on package manager and choices - Deploy: Cloudflare deployment adds
packages/infra/alchemy.run.tsand related infra files
This reflects the actual files written by the CLI so new projects match what's documented here.