Leave Localhost logoLeave LocalhostDocs

Project Structure

Leave Localhost is a Turborepo monorepo with three Next.js apps, one Convex backend package, and shared internal packages.

Leave Localhost is a Turborepo monorepo with three Next.js apps, one Convex backend package, and shared internal packages.

Top Level

.
├── apps/
│   ├── app/
│   ├── marketing/
│   └── docs/
├── packages/
│   ├── analytics/
│   ├── backend/
│   ├── config/
│   ├── email/
│   └── ui/
├── tooling/
│   ├── env-doctor/
│   └── typescript/
├── docs/
├── AGENTS.md
├── biome.json
├── package.json
├── turbo.json
└── tsconfig.json

Apps

apps/app is the authenticated product app. It uses Next.js App Router with localized routes under src/app/[locale].

Important areas:

  • src/app/[locale]/(dashboard): signed-in product routes.
  • src/app/[locale]/(public): login, invitation, and auth challenge routes.
  • src/app/api/auth/[...route]: Better Auth route handler.

apps/marketing is the public marketing site. Keep marketing pages, blog and changelog content, and other public content here.

apps/docs is the documentation site. It is a Fumadocs + Next.js app that renders the repository root docs/ directory; it does not store its own content. See the Documentation section below.

Packages

packages/backend owns Convex code:

  • schema
  • queries, mutations, and actions
  • Better Auth integration
  • billing adapters and webhooks
  • invitations and memberships
  • permissions and capabilities
  • sensitive-action protection
  • email integration
  • rate limiting

Do not manually edit packages/backend/convex/_generated/**.

packages/config contains browser-safe static product identity shared by the Next.js apps. Customize src/brand.ts for names, labels, default copy, logo alt text, GitHub URL, and support email. It never reads environment variables; each deployable owns and validates its runtime URLs locally.

packages/ui contains shared shadcn/Radix/Tailwind UI. Put reusable UI here when both apps can use it. Product-only UI belongs in apps/app; marketing-only UI belongs in apps/marketing.

packages/email is the React Email preview server. It does not hold templates; each file under emails/ imports a backend template and supplies sample props. The templates themselves live in packages/backend/convex/email/templates.

packages/analytics is the provider-neutral analytics boundary (PostHog and no-op implementations). The Convex backend facade lives in packages/backend/convex/analytics.

Logging is not a package: the backend uses Convex's native logs and the Next.js apps use the platform console. See Logging.

Tooling

tooling/env-doctor validates local environment files and powers:

bun check-env
bun setup:doctor

tooling/typescript holds shared TypeScript workspace configuration.

Documentation

Root docs/*.md files cover general setup and operations. Feature-specific documentation lives in folders such as docs/auth, docs/billing, docs/security, and docs/recipes. Each folder may include a meta.json that sets its sidebar label and page order.

Keep root docs focused on orientation and cross-cutting setup. Put detailed feature behavior in the matching feature folder.

The apps/docs app renders this directory with Fumadocs, so Markdown files use YAML frontmatter (title, description) and internal links are extensionless routed paths (for example /billing/overview, not ./billing/overview.md). Run bun dev:docs to preview the site at http://localhost:3004.

Ownership Rules

  • Shared UI: packages/ui.
  • Product-only UI and authenticated workflows: apps/app.
  • Marketing-only pages and components: apps/marketing.
  • Convex backend, auth, billing, webhooks, and schema: packages/backend/convex.
  • Service setup checks and env validation: tooling/env-doctor.
  • Setup, command, and environment documentation: README.md and docs.

Build System

Root scripts are Turborepo entrypoints. Package scripts define the actual work. This lets Turbo run tasks in dependency order and cache safe outputs.

Common root scripts:

bun dev
bun run lint
bun run typecheck
bun run test
bun run build

When adding a new app or package, define package-level scripts first, then wire them into turbo.json only when the task should participate in repo workflows.

On this page