Nextbase Docs
Nextbase Docs
HomeBlogWelcome to Nextbase v5!Choose your starterGetting startedLocal Supabase per agent
Next.js + SupabaseInstallationEnvironment variablesAuthenticationAgent connectionsProject structureDeployment
AuthenticationWorkspaces and the admin area
Building with agentsEmails with Resend
TroubleshootingNextbase v5
The 8 starter kitsNext.js + Supabase

Project structure

The monorepo layout of the Next.js + Supabase starter, including the separate admin app, and where to make each kind of change.

The kit is a Turborepo workspace managed with pnpm. pnpm-workspace.yaml includes apps/* and packages/*. Root scripts in package.json fan out through turbo.json.

Repository tree

proxy.ts
environment.d.ts
.env.local.example
.env.test
next.config.ts
netlify.toml
instrumentation.ts
vitest.config.mts
package.json
proxy.ts
environment.d.ts
.env.local.example
.env.test
next.config.ts
vitest.config.mts
package.json
config.toml
seed.sql
package.json
setup.sh
turbo.json
pnpm-workspace.yaml
package.json
.nvmrc
AGENTS.md
CHANGELOG.md

The four apps

apps/web is the product: a Next.js 16 App Router app with Cache Components enabled in next.config.ts. It depends on database for generated types and on @nextbase/typescript-config for the shared tsconfig. Its next.config.ts derives the Supabase Storage image pattern from NEXT_PUBLIC_SUPABASE_URL.

apps/admin is the administration app (package name admin, next dev --port 3002). It serves /app-admin, the feedback and roadmap moderation views, the Admin MCP and the support sign-in flow, and it deploys independently from the web app against the same Supabase project. Root scripts pnpm admin#dev and pnpm admin#build target it. docs/admin-app.md describes the split.

apps/database owns Supabase. supabase/config.toml configures the local project with the stack engine enabled, supabase/migrations/ holds the SQL migrations, supabase/seed.sql seeds test users and content, and supabase/tests/ holds pgTap suites. lib/database.types.ts is generated and exported as database/types. The package pins the supabase CLI to 2.121.0.

apps/email is the React Email preview server (pnpm --filter @nextbase/email dev, port 3001). The templates in emails/ are the design source; the web app renders its own copies with @react-email/* components.

Where to make changes

Routes and pages

Web routes are under apps/web/src/app, grouped by access level:

  • (external-pages): landing page, /blog, /changelog, /terms, /docs entry.
  • (dynamic-pages)/(login-pages): /login, /sign-up.
  • (dynamic-pages)/(misc-login-pages): /forgot-password, /update-password, /confirm-delete-user, /auth/callback, /auth/confirm.
  • (dynamic-pages)/(updates-pages): public /feedback and /roadmap.
  • (dynamic-pages)/(authenticated-pages): /dashboard, /onboarding, /user/*, (application-pages)/workspace/[workspaceSlug]/* (home, projects, settings with billing and members) and (application-pages)/project/[projectSlug].
  • api/: stripe/webhooks, invitations, chat, search, revalidate, internal/admin-revalidate (called by the admin app), token/refresh, health, v1/me and the OG image routes.
  • mcp/[...path], oauth/[...path] and .well-known/*: the User MCP route handlers.

Admin routes are under apps/admin/src/app: app-admin/(admin-pages)/* (dashboard, users, workspaces, marketing/{blog,changelog,authors,tags}, payment-gateway/{customers,invoices,subscriptions}, settings), (dynamic-pages)/(updates-pages) for feedback and roadmap moderation, api/admin/marketing/media, login, logout, auth/{callback,confirm} and the Admin MCP handlers under mcp, oauth and .well-known.

When you add a protected web route, add its matcher to apps/web/src/middlewares/paths.ts, otherwise proxy.ts will not run the auth chain for it. The admin app's proxy.ts uses a fixed matcher for /app-admin, /feedback and /roadmap.

Server and data access

Web database access is in apps/web/src/data/, split into user/ (RLS-scoped, user session), anon/ (public marketing data) and auth/ (sign-in actions). Admin queries that need the service-role client live in apps/admin/src/data/admin/, gated by adminActionClient from apps/admin/src/lib/safe-action.ts. Files there start with "use server". Server actions are built with next-cool-action wrappers (apps/web/src/lib/safe-action.ts and the admin equivalent).

Pick the Supabase client that matches the context from src/supabase-clients/ in each app: server component, server action, route handler, middleware, browser, admin or (web only) Unkey.

Schema and migrations

Add a timestamped SQL file to apps/database/supabase/migrations/. Enable RLS on every new table and write its policies in the same file. Then:

pnpm --filter database exec supabase db reset --local
pnpm gen-types-local
pnpm --filter database test-db

Add a pgTap test under apps/database/supabase/tests/ for the new policies. Use pnpm --filter database exec supabase migration list --local to check what is applied.

Authentication

Server actions in apps/web/src/data/auth/auth.ts, UI in apps/web/src/components/authentication/, middleware in apps/web/src/middlewares/, claims schema in apps/web/src/utils/zod-schemas/user-claims-schema.ts, admin check in utils/is-supabase-user-app-admin.ts (both apps). Admin login and gate in apps/admin/src/app/login/ and apps/admin/src/proxy.ts. Local Auth settings are in apps/database/supabase/config.toml. See authentication.

Emails

Templates in apps/email/emails/. Sending goes through src/utils/api-routes/utils.ts in each app, which chooses Mailpit (USE_LOCAL_EMAIL=true) or Resend. The web copy of send-email-mailpit.ts reads MAILPIT_URL. Invitation and notification emails are triggered from apps/web/src/data/user/invitation.tsx and apps/web/src/data/user/user.tsx.

Billing

apps/web/src/payments/abstract-payment-gateway.ts defines the interface; stripe-payment-gateway.ts implements it (the admin app has its own copy under apps/admin/src/payments/). The webhook route is apps/web/src/app/api/stripe/webhooks/route.ts. Self-service billing UI is under workspace/[workspaceSlug]/settings/billing in the web app; the payment gateway admin pages are under apps/admin/src/app/app-admin/(admin-pages)/payment-gateway.

Content publishing across apps

Blog, changelog and feedback are edited in the admin app and read by the web app. After a publish, apps/admin/src/lib/revalidate-web-app.ts posts to the web app's /api/internal/admin-revalidate with the shared REVALIDATE_SECRET so the web app's cached pages refresh.

Background work

There is no job queue or worker in this kit. Stripe webhooks, Supabase Realtime channels and the on-demand POST /api/revalidate endpoint are the asynchronous entry points.

MCP

src/mcp/ in each app holds the protocol core, the Supabase adapter and the record store; the route files under app/mcp, app/oauth and app/.well-known are one-liners. The web copy serves the user audience, the admin copy the admin audience. See agent connections.

Tests

  • Unit tests sit next to the code as *.test.ts and run with pnpm test (Vitest with --root src in both web and admin).
  • Browser tests are in apps/web/e2e/ (anon, user, admin, invitations, password-updation, with _setups and _helpers) and run with pnpm test-integration using apps/web/playwright/playwright.config.mts. The config starts both the web and admin production servers; the admin specs run against the admin origin.
  • Database tests are in apps/database/supabase/tests/ and run with pnpm --filter database test-db.
  • pnpm verify:local runs lint, typecheck, unit tests and a compile-mode build of the web app; pnpm signoff runs it and posts a signoff status with the gh-signoff extension.

The nightly integration-tests.yml workflow starts Supabase, resets the database, runs pgTap, builds and runs Playwright. release.yml opens a Changesets version PR on pushes to main.

Agent connections

The User MCP and Admin MCP of the Next.js + Supabase starter: endpoints on the web and admin origins, tools, consent flow and where the code lives.

Deployment

Provision a Supabase project, apply migrations and deploy the Next.js + Supabase starter's web and admin apps to Vercel.

On this page

Repository treeThe four appsWhere to make changesRoutes and pagesServer and data accessSchema and migrationsAuthenticationEmailsBillingContent publishing across appsBackground workMCPTests