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:

package.json
bts.jsonc
turbo.json
pnpm-workspace.yaml
bunfig.toml
.npmrc
README.md

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)

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

header.tsx
loader.tsx
mode-toggle.tsx
theme-provider.tsx
main.tsx
index.css
index.html
components.json
tsconfig.json
vite.config.ts
package.json

Next.js

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

index.ts
package.json
tsconfig.json

Express / Fastify / Elysia

index.ts
package.json
tsconfig.json

Next (backend)

middleware.ts
next.config.ts
tsconfig.json
package.json

Workers runtime (optional)

When runtime=workers, you'll also get:

wrangler.jsonc

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

drizzle.config.ts

Prisma ORM

schema.prisma

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):

_layout.tsx
index.tsx
app.json
package.json
tsconfig.json

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:

astro.config.mjs
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|lefthook|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.

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.

On this page