Project Structure

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)

{
  "$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|next|convex>",
  "runtime": "<bun|node|workers>",
  "frontend": ["<next|tanstack-router|react-router|tanstack-start|nuxt|svelte|solid>"] ,
  "addons": ["<turborepo|biome|husky|pwa|starlight>"] ,
  "examples": ["<ai|todo|none>"] ,
  "auth": <"better-auth"|"clerk"|"none">,
  "packageManager": "<bun|pnpm|npm>",
  "dbSetup": "<none|docker|d1>",
  "api": "<none|trpc|orpc>",
  "webDeploy": "<none|wrangler|alchemy>",
  "serverDeploy": "<none|wrangler|alchemy>"
}

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

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:

{
  "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: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.