--- title: Project Structure description: Understanding the structure of projects created by Better-T-Stack CLI --- ## Overview Better-T-Stack CLI scaffolds a monorepo with `apps/*` and, when needed, `packages/*`. The exact structure depends 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: ``` / ├── apps/ # Applications (web, server, native, docs) ├── packages/ # Only when needed (e.g. Convex backend) ├── package.json # Root package.json (scripts updated by CLI) ├── bts.jsonc # Better‑T Stack configuration (always written) ├── turbo.json # Only when addon "turborepo" is selected ├── pnpm-workspace.yaml # Only when packageManager=pnpm ├── bunfig.toml # Only when packageManager=bun ├── .npmrc # pnpm + (native or nuxt) for alias resolution └── README.md # Generated quickstart ``` Notes: - `bts.jsonc` lets the CLI detect and enhance your project later; keep it if you plan to use `bts add`. - `turbo.json` exists only if you picked the Turborepo addon. ## Monorepo structure by backend ### Non-Convex backends (hono, express, fastify, elysia, next) ``` my-app/ ├── apps/ │ ├── web/ # Present if you picked a web framework │ ├── server/ # Backend API (framework depends on your choice) │ ├── native/ # Present if you picked React Native (Expo) │ └── docs/ # Present if you picked the Starlight/Fumadocs addon └── packages/ # May exist but not used by default ``` ### Convex backend ``` my-app/ ├── apps/ │ ├── web/ # Present if you picked a web framework │ ├── native/ # Present if you picked React Native (Expo) │ └── docs/ # Present if you picked the Starlight/Fumadocs addon └── packages/ └── backend/ # Convex functions, schema and config ``` ## 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 ``` apps/web/ ├── src/ │ ├── components/ │ │ ├── ui/ # shadcn/ui primitives (from web base) │ │ ├── header.tsx │ │ ├── loader.tsx │ │ ├── mode-toggle.tsx │ │ └── theme-provider.tsx │ ├── routes/ │ │ ├── __root.tsx # Root layout │ │ └── index.tsx # Home │ ├── lib/ │ │ └── utils.ts │ ├── utils/ │ │ └── trpc.ts (API=trpc) | orpc.ts (API=orpc) │ ├── main.tsx │ └── index.css ├── index.html ├── components.json # shadcn/ui config ├── tsconfig.json ├── vite.config.ts └── package.json ``` ### Next.js ``` apps/web/ ├── src/ │ ├── app/ │ │ ├── layout.tsx │ │ └── page.tsx │ └── components/ │ ├── mode-toggle.tsx │ ├── providers.tsx │ └── theme-provider.tsx ├── components.json ├── next.config.ts ├── postcss.config.mjs ├── tsconfig.json └── package.json ``` Notes: - If you choose `backend=next`, the backend is scaffolded separately in `apps/server`. The web app does not include API routes. - (auth) adds `src/app/login/*` and `src/app/dashboard/*` plus sign-in components. ## Backend Structure (apps/server) The server structure depends on your backend choice: ### Hono backend ``` apps/server/ ├── src/ │ ├── routers/ │ │ └── index.ts # Base router │ └── index.ts # Hono app entry ├── package.json └── tsconfig.json ``` ### Express / Fastify / Elysia ``` apps/server/ ├── src/ │ └── index.ts # Framework entry ├── package.json └── tsconfig.json ``` ### Next (backend) ``` apps/server/ ├── src/ │ ├── app/ │ │ └── route.ts # App Router endpoint │ └── middleware.ts ├── next.config.ts ├── tsconfig.json └── package.json ``` ### Workers runtime (optional) When `runtime=workers`, you’ll also get: ``` apps/server/ └── wrangler.jsonc # Cloudflare Workers config (template) ``` 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 ``` apps/server/ ├── src/db/ │ └── index.ts # Database connection ├── drizzle.config.ts # Drizzle configuration └── drizzle/ # Generated migrations (after you run commands) ``` ### Prisma ORM ``` apps/server/ └── prisma/ ├── schema.prisma # Database schema └── migrations/ # Generated after running Prisma commands ``` ### Mongoose (MongoDB) ``` apps/server/ └── src/db/ └── index.ts # Mongoose connection ``` ### 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): ``` apps/native/ ├── app/ # App screens │ ├── (tabs)/ # Tab navigation │ ├── _layout.tsx # Root layout │ └── index.tsx # Home screen ├── components/ # React Native components ├── lib/ # Utilities ├── assets/ # Images, fonts ├── app.json # Expo configuration ├── package.json # Dependencies └── tsconfig.json # TypeScript config ``` If an API is selected, a client utility is added: - API=trpc: `utils/trpc.ts` - API=orpc: `utils/orpc.ts` ## Documentation Structure (apps/docs) When using Starlight or Fumadocs addon: ``` apps/docs/ ├── src/ │ ├── content/ # Documentation content │ │ └── docs/ # Doc pages │ └── pages/ # Astro pages (Starlight) ├── astro.config.mjs # Astro config (Starlight) ├── package.json └── tsconfig.json ``` ## Configuration Files ### Better-T-Stack Config (bts.jsonc) ```json { "$schema": "https://r2.better-t-stack.dev/schema.json", "version": "", "createdAt": "", "database": "", "orm": "", "backend": "", "runtime": "", "frontend": [""] , "addons": [""] , "examples": [""] , "auth": <"better-auth"|"clerk"|"none">, "packageManager": "", "dbSetup": "", "api": "", "webDeploy": "", "serverDeploy": "" } ``` ### Turborepo Config (turbo.json) Generated only if you chose the Turborepo addon. ```json { "$schema": "https://turbo.build/schema.json", "tasks": { "build": { "dependsOn": ["^build"], "outputs": ["dist/**", ".next/**"] }, "dev": { "cache": false, "persistent": true } } } ``` ## Shared packages By default, no shared packages are created. You will see `packages/backend` only when using the Convex backend. You can add more packages manually as your repo grows. ``` packages/ └── backend/ # Only with Convex backend ``` ## Development Scripts Scripts are adjusted based on your package manager and whether the Turborepo addon is selected. With Turborepo: ```json { "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): ```json { "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:setup` for initial backend configuration. ## Key Details - **Monorepo**: `apps/*` always; `packages/*` only when needed (Convex) - **React web base**: shadcn/ui primitives, `components.json`, common utilities - **API clients**: `src/utils/trpc.ts` or `src/utils/orpc.ts` added to web/native when selected - **Auth**: Adds authentication setup based on provider: - `better-auth`: `src/lib/auth.ts` on server and login/dashboard pages on web app - `clerk`: Clerk provider setup and authentication components - **ORM/DB**: Drizzle/Prisma/Mongoose files added only when selected - **Extras**: `pnpm-workspace.yaml`, `bunfig.toml`, or `.npmrc` added based on package manager and choices - **Deploy**: Workers deploy adds `wrangler.jsonc` templates to the appropriate app(s) This reflects the actual files written by the CLI so new projects match what’s documented here.