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.jsonApps
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:doctortooling/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.mdanddocs.
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 buildWhen 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.