Project Structure

Understanding the monorepo structure and organization.

Learn how the codebase is organized and where to find things.

Monorepo Overview

This project uses Turborepo to manage a monorepo with multiple apps and packages.

project-root/
├── apps/                    # Applications
│   ├── web/                # Main TanStack Start app
│   └── e2e/                # Playwright E2E tests
├── packages/               # Shared packages
│   ├── features/           # Feature packages
│   ├── ui/                 # UI components
│   ├── supabase/           # Supabase clients
│   └── function-middleware/ # Server-function middleware
├── tooling/                # Development tools
└── docs/                   # Documentation

Main Application (apps/web)

The primary TanStack Start application:

apps/web/
├── src/
│   ├── routes/             # File-based routes (TanStack Router)
│   ├── components/         # Shared components
│   ├── config/             # Configuration files
│   └── lib/                # Server functions + utilities
├── content/                # Docs & marketing content (.mdoc)
├── supabase/               # Database schema, migrations, tests
└── public/                 # Static assets

Route Structure

Routes live in apps/web/src/routes and use TanStack Router's file-based routing. route.tsx defines a layout for a folder, index.tsx its index page, a _-prefixed folder is a pathless layout (shares a layout without adding a URL segment), and $param is a dynamic segment. The route tree is generated into routeTree.gen.ts — never edit it by hand.

src/routes/
├── _marketing/             # Public pages (pathless: no /_marketing in the URL)
│   ├── index.tsx           # → /
│   └── pricing.tsx         # → /pricing
├── auth/                   # Sign in / up, callback, MFA verify
├── _authenticated/         # Guard shell: loads the active-account workspace
│   ├── route.tsx           # Auth + MFA gate, provides the workspace context
│   ├── dashboard/          # Main app (its own sidebar)
│   │   ├── route.tsx       # → /dashboard layout
│   │   └── index.tsx       # → /dashboard
│   ├── settings/           # Settings section (its own sidebar)
│   │   ├── index.tsx       # → /settings
│   │   ├── members.tsx     # → /settings/members
│   │   └── billing/        # → /settings/billing
│   └── create-team.tsx     # → /create-team
├── admin/                  # Super-admin panel
├── join/                   # Team invitation acceptance
└── api/                    # Server route handlers

There is no account slug in these URLs. The active account (personal or team) is resolved from the database, so the same static paths serve every workspace.

Packages Structure

Feature Packages (packages/features/)

packages/features/
├── accounts/               # Personal account management
├── auth/                   # Authentication
├── team-accounts/          # Team management, invitations
├── admin/                  # Super admin
└── notifications/          # In-app notifications

Infrastructure Packages

packages/
├── ui/                     # Shadcn UI + design system (@kit/ui)
├── supabase/               # Database clients + types (@kit/supabase)
├── function-middleware/    # Server-function auth middleware
└── billing/               # Subscription logic

Supabase (apps/web/supabase/)

apps/web/supabase/
├── schemas/                # Declarative SQL schemas (numbered by dependency)
├── migrations/             # Generated migrations
└── tests/database/         # pgTAP tests

Configuration Files

apps/web/src/config/
├── paths.config.ts             # Route paths (slug-free)
├── billing.config.ts           # Billing settings
├── feature-flags.config.ts     # Feature flags
└── navigation.config.tsx       # Main app sidebar navigation

The settings sidebar is configured separately in apps/web/src/components/settings/settings-navigation.tsx.

Server Functions

Server logic uses createServerFn from @tanstack/react-start, kept in *.functions.ts files (loaders) with mutations suffixed Function. Data is fetched in route loaders / beforeLoad and flowed down through context providers.

import { createServerFn } from '@tanstack/react-start';
import { authFunctionMiddleware } from '@kit/function-middleware/functions';

export const myFunction = createServerFn({ method: 'POST' })
  .middleware(authFunctionMiddleware) // context.user available
  .validator(MySchema)
  .handler(async ({ data, context }) => {
    /* ... */
  });

Import Paths

// Packages
import { Button } from '@kit/ui/button';
import { getSupabaseServerClient } from '@kit/supabase/server-client';

// Within apps/web (the `#/` alias points at apps/web/src)
import pathsConfig from '#/config/paths.config.ts';
import { useWorkspace } from '#/components/workspace-context.tsx';

Finding Your Way

Looking for...Location
Routesapps/web/src/routes/
UI Componentspackages/ui/src/
Database Schemaapps/web/supabase/schemas/
Server functionsapps/web/src/lib/server/*.functions.ts
Auth Logicpackages/features/auth/
Team Featurespackages/features/team-accounts/
Config Filesapps/web/src/config/