Skip to main content
The web app has two modes selected by NEXT_PUBLIC_APP_MODE. The choice is baked at build time — there is no runtime toggle. Self-hosted vs cloud mode

Detection

apps/web/src/lib/config/app.ts derives the mode at module load:
  • If NEXT_PUBLIC_APP_MODE is set explicitly → use that.
  • Otherwise, if NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY is set → cloud.
  • Otherwise → self-hosted.
apps/web/src/middleware.ts picks the right middleware at import time:
Because Next.js middleware is bundled per build, this means changing modes requires a rebuild, not just an env-var swap on a running server.

Why a flag, not two apps?

The same React tree, store, and routes run in both modes. Adding a second app would double the surface area without adding behavior. The flag pattern keeps:
  • One template gallery
  • One editor state machine
  • One set of components
…and only switches the edges — auth middleware, sync side-effects, AI Lab visibility.
Do not add new runtime mode toggles or local/cloud branches without strong justification. The current split is intentionally narrow. See the contributing guide.

Adding a new cloud-only feature

  1. Gate the UI on APP_MODE === 'cloud' (or a more specific capability flag if it applies to BYO-Clerk users only).
  2. Put network calls behind httpClient.api so the auth interceptor handles tokens.
  3. Make sure the feature degrades gracefully in self-hosted — empty state, not crash.
  4. Add a row to the env-var table in Cloud Mode if it needs new config.