Leave Localhost logoLeave LocalhostDocs
Architecture

Architecture Overview

Leave Localhost is a full-stack SaaS starter built on Next.js (frontend) and Convex (backend), structured as a Turborepo monorepo. It ships authentication, multi-tenancy, billing, transactional email, analytics, and error tracking so you can focus on product code.

Leave Localhost is a full-stack SaaS starter built on Next.js (frontend) and Convex (backend), structured as a Turborepo monorepo. It ships authentication, multi-tenancy, billing, transactional email, analytics, and error tracking so you can focus on product code.

Tech Stack

LayerTechnology
Frontend frameworkNext.js 15 (App Router)
BackendConvex (real-time, serverless)
AuthenticationBetter Auth (via @convex-dev/better-auth)
BillingPolar, Stripe, or Lemon Squeezy (pluggable)
UI componentsshadcn/ui, Radix, Tailwind CSS 4
EmailResend + React Email
AnalyticsPostHog (optional)
Error trackingSentry
LoggingConvex-native logs (backend) + platform console (apps)
MonorepoTurborepo + Bun
ValidationZod, @t3-oss/env-core

High-Level Flow

┌──────────────────────────────┐
│        User's Browser        │
├──────────────────────────────┤
│  apps/app (Next.js)          │  ◄── Authenticated product app
│  apps/marketing (Next.js)    │  ◄── Marketing site
├──────────────────────────────┤
│  packages/ui                 │  ◄── Shared components & tokens
│  packages/analytics          │  ◄── PostHog + no-op (provider-neutral)
│  packages/email              │  ◄── React Email preview workspace
└──────────┬───────────────────┘
           │ Convex client SDK (real-time subscriptions, mutations, actions)

┌──────────────────────────────┐
│  packages/backend/convex     │
│  ─────────────────────────── │
│  Schema, queries, mutations, │
│  actions, auth, billing,     │
│  permissions, email,         │
│  webhooks, cron jobs         │
└──────────┬───────────────────┘

    ┌──────┴──────┐
    │  Convex DB  │  ◄── Transactional, real-time document database
    └─────────────┘

Key Design Decisions

Backend as a Package

The Convex backend is a standalone package at packages/backend rather than co-located with the frontend. This lets both apps/app and apps/marketing import backend types and client bindings without duplicating schema definitions.

Capability-Based Permissions

Permissions combine role-based access (via Better Auth organizations) with capability-based entitlements (granted by billing plans). A function can require both a specific role and a specific capability, ensuring that paid features remain locked even if a user has the correct role.

Provider-Agnostic Billing

Billing is abstracted behind a BillingProviderAdapter interface and ships opt-in. All provider integrations are compiled in and registered in billing/providers.ts; a provider is activated solely by setting BILLING_PROVIDER. With it unset, no webhook route is registered and billing is disabled. Webhooks from the active provider converge into a shared grant system — the rest of the codebase checks capabilities, not provider-specific subscription states.

Real-Time by Default

Convex queries are reactive subscriptions. When data changes in the database, all connected clients that subscribe to affected queries receive updated results automatically. The dashboard uses this for the optional workspace records demo, member lists, and billing state.

Next Reads

On this page