Project Structure and Organization

Understand the current monorepo layout, route tree, and key config locations.

The TanStack Start Drizzle SaaS Kit is organized as a pnpm + Turborepo monorepo.

Top-Level Layout

apps/ # runnable apps
packages/ # shared packages
tooling/ # shared tooling and MCP server
turbo/ # code generators
docs/ # documentation

Apps

apps/
├── web/ # main TanStack Start app
└── e2e/ # Playwright test app

apps/web

This is a TanStack Start (Vite + Nitro) application. Source lives under src/, not a Next.js app/ directory.

Key locations:

apps/web/
├── src/
│ ├── routes/ # file-based route tree (TanStack Router)
│ ├── components/ # app components (kebab-case)
│ ├── config/ # typed app config (app, auth, feature flags, ...)
│ ├── lib/ # server functions, loaders, helpers
│ ├── styles/ # global styles
│ ├── router.tsx # router instance
│ ├── start.ts # global request middleware (CSRF, security headers)
│ ├── routeTree.gen.ts # generated route tree (do not edit by hand)
│ └── env.d.ts # typed import.meta.env
├── content/ # CMS content (posts, changelog, documentation)
├── public/ # static assets
├── vite.config.ts # Vite + TanStack Start + Nitro config
└── tsr.config.json # TanStack Router generator config

Notes:

  • app config files live in apps/web/src/config/
  • the sidebar/navigation config lives in apps/web/src/config/navigation.config.tsx
  • inside apps/web, the #/* import alias maps to ./src/* (e.g. #/config/app.config)
  • Drizzle config does not live in apps/web; it lives in packages/database/drizzle.config.mjs

Routing

Routes are file-based under apps/web/src/routes/. TanStack Router generates routeTree.gen.ts from these files.

src/routes/
├── __root.tsx # root route: shell, head, providers, beforeLoad
├── _public/ # marketing/public pages (pathless group)
├── _authenticated/ # signed-in app (dashboard, settings, billing)
├── _invitation/ # invitation acceptance flow
├── auth/ # sign-in, sign-up, password reset, MFA verify
├── admin/ # admin pages
├── help/ # documentation/help pages
├── api/ # server routes (auth catch-all, upload, healthcheck)
├── sitemap[.]xml.ts # sitemap server route
└── robots[.]txt.ts # robots server route

Route conventions (TanStack Router):

  • a pathless layout group is a folder prefixed with _ (e.g. _public/, _authenticated/) with a route.tsx layout
  • a folder/segment route uses route.tsx; its default child is index.tsx
  • dynamic params use $param (e.g. blog/$slug.tsx); catch-all uses $.tsx (e.g. help/$.tsx)
  • API/server routes are plain .ts files under api/ using createFileRoute(...).methods(...) / server handlers

There is no [locale] path segment. Locale is cookie-based (LOCALE_COOKIE / detectLocale()); see the Internationalization docs.

Naming Conventions

  • routes: route.tsx, index.tsx, $param.tsx, $.tsx
  • loaders/server functions: colocated in src/lib/** (e.g. *.functions.ts) or inside the route file
  • schemas: *.schema.ts
  • components: kebab-case.tsx

Package Layout

Most packages expose from src/index.ts and define additional exports in package.json.

Use pnpm turbo gen package if you need a new shared package.


Next: Packages →