Browse documentation

Studio is a Next.js 15 App Router app on React 19 (apps/studio). One build serves two products:

ProductServed byYou get
Platform Consoleapps/server/console/server.tsOrg, projects, team, usage, billing, platform settings
Project StudioA project's own API serverThe project surfaces — tables, SQL, auth, storage, logs…

Both mount under the same basePath: '/studio', fixed in next.config.mjs — Next has no runtime basePath, so the prefix cannot be chosen per deployment. Because the pathname no longer tells the two products apart, the Console server stamps an mb_product=console cookie on every non-API response it serves, and src/shared/lib/project.ts reads it. No cookie means Project Studio, which is the safer default: the shell then skips the platform-only calls a project API cannot answer.

Note

next.config.mjs is deliberately .mjs, not .ts. The API server loads it at runtime through nextApp.prepare(), and the production image runs npm prune --omit=dev, so TypeScript is gone by then — Next reacted by shelling out to install it inside the container on every boot. A .mjs config needs no compiler at runtime.

App shell

Route files live in apps/studio/app/; the shell components they compose live in apps/studio/src/shell/.

FileRole
app/layout.tsxRoot document, fonts, theme
app/providers.tsxReact Query and app-level context
app/client-gate.tsxDefers client-only work until after hydration
src/shell/Layout.tsxChrome for platform-level screens
src/shell/OrgLayout.tsxOrg-scoped shell (org switcher) — app/(org)/
src/shell/ProductLayout.tsxTwo-tier product panels (database, auth, observability)
src/shell/RequireAuth.tsxRequireAuth, RequirePasswordChange, RequirePlatformCapability, RequirePlatformFeature
src/shell/ProjectGate.tsxResolves /p/:id and blocks the project shell until the project is known
app/not-found.tsx / src/shell/NotFound.tsx404

Guards map onto the Console's model: RequirePlatformCapability capability="users.manage" gates Team, RequirePlatformFeature feature="billing" gates Billing (off unless CONSOLE_BILLING_ENABLED=true). See capabilities.

Platform routes

PathPage
/loginSign in
/password-change-requiredForced rotation
/Projects
/newCreate project
/teamTeam (needs users.manage)
/usageUsage
/logsPlatform logs
/billingBilling (feature-gated)
/settingsOrg settings
/git/callbackGitHub OAuth return page
/system→ /settings

Project routes (/p/:id/*)

PathPageDocs
overviewProject overview
connectConnection strings and keys
branchesProject branches, custom domains, database access and JWT keys
tables, tables/:modelTable editorTable editor
sqlSQL editorSQL editor
storageBuckets and objectsStorage
logsLog streamLogs & observability
advisorAdvisor findings
realtimeRealtime inspector
apiAPI explorerAPI tools
edge-functionsEdge functions
integrationsIntegrations
settingsProject settings

A catch-all [...unknown] under /p/:id/ renders the 404 inside the project shell rather than dropping the reader out of it.

database/*

The database product includes schemas, tables, functions, triggers, types, extensions, indexes, publications, roles, column-privileges, settings, migrations, backups, webhooks, cron, and queues. The index redirects to the database overview. See Database screens.

auth/*

Index is Users; then policies, access, providers, sessions, mfa, rate-limits, url-configuration, protection, third-party, hooks, audit, passkeys, organizations, and settings. The access page is the Role Access matrix; the query simulator is available through the CLI/MCP, not as a Studio route. See Authentication screens.

observability/*

Index overview, plus api, database, and reports.

Integrations

The integrations product contains the catalogue at integrations, plus vault and wrappers. Database queues are documented separately from these integrations.

Products

The product switcher exposes overview, tables, sql, database, auth, storage, realtime, edge-functions, integrations, branches, advisor, observability, logs, api, connect, and settings. Some entries are cross-links into the project routes above rather than additional route families.

Moved routes

Paths that moved are declared once in the MOVED map in next.config.mjs and served as permanent (308) redirects, so they cost nothing at runtime:

FromTo
/p/:id/p/:id/overview
/p/:id/database/p/:id/database/functions
/p/:id/functions, triggers, extensions, migrations, backups, webhooks, cronthe matching /p/:id/database/*
/p/:id/policies/p/:id/auth/policies
/p/:id/auth/users/p/:id/auth
/p/:id/reports/p/:id/observability
/system/settings

Feature layout

Every feature folder follows the same shape:

features/<name>/
  api/        typed calls to the admin API
  components/ presentational pieces
  hooks/      data loading and state
  lib/        pure helpers
  pages/      route entries
  types.ts

Features: api-tools, assistant, auth, database, integrations, logs, platform, projects, sql, storage, tables. Shared building blocks live in src/shared.

Mock mode

npm run studio:dev      # next dev on :5173, proxying /api to localhost:5001
npm run studio:mock     # the same, with NEXT_PUBLIC_MOCK=1
npm run studio:build    # next build

Mock mode sets NEXT_PUBLIC_MOCK=1 and installs an MSW service worker that answers from src/mocks/handlers.ts, so you can work on screens with no backend and no database. It is set by a small apps/studio/scripts/dev-mock.mjs wrapper rather than an inline VAR=value prefix, which would not work on Windows.

Dev and production write to different build directories — .next-dev and .next. Running npm run build at the repo root while a Studio dev server is up used to overwrite the dev manifests underneath it, and every page then 500'd with "Could not find the module … in the React Client Manifest".

In development Next also rewrites /api/:path* to http://localhost:5001 with basePath: false, so the axios base URL of /api reaches the API server rather than /studio/api. In production Express owns /api and never forwards it to Next.

How it talks to the backend

Every project screen calls /api/admin/*. Under the Console, those calls go to /api/projects/:id/admin/* and are proxied with the project's platform token — see Project proxy. Under a project's own /studio mount they hit that project's admin API directly with the operator's session.

Platform screens

The org, projects, team, usage and billing screens served at the Console root are documented in Platform & project screens.