Nextbase Docs
Nextbase Docs
HomeBlogWelcome to Nextbase v5!Choose your starterGetting startedLocal Supabase per agent
TanStack + NeonInstallationEnvironment variablesAuthenticationAgent connectionsProject structureDeployment
AuthenticationWorkspaces and the admin area
Building with agentsEmails with Resend
TroubleshootingNextbase v5
The 8 starter kitsTanStack + Neon

Installation

Run the TanStack + Neon starter locally with Docker, apply migrations and seed data, start the web and admin apps, and create your first account.

Local development doesn't need a Neon account. Docker Compose provides PostgreSQL 18, PgBouncer, Mailpit and MinIO, and the apps connect to those with the defaults in .env.example. You need Node.js 24, pnpm 11.1.2 and Docker with Compose. The shared getting started page has the general flow; this page has the exact commands for this kit.

Clone the repository

git clone https://github.com/usenextbase/tanstack-planetscale-starter.git
cd tanstack-planetscale-starter

The repository keeps its older PlanetScale name. The database is Neon Postgres in production and plain PostgreSQL in Docker locally.

Enable pnpm through corepack

corepack enable
pnpm --version

The packageManager field pins pnpm 11.1.2. Corepack uses that version automatically. .npmrc sets engine-strict=true, so an older Node.js fails at install time.

Create the env file

[ -f .env ] || cp .env.example .env

Docker Compose reads .env for the published ports. The Node processes read process.env and fall back to defaults in apps/web/src/server/env.ts that match .env.example, so a first run works without changing anything. Nothing in the repository loads .env into the Node processes for you: when you change an application value such as BETTER_AUTH_SECRET, export it in the shell that runs pnpm dev or use an env loader of your choice. See environment variables for what each value does.

The admin app has its own small template at apps/admin/.env.example. Locally you can leave it alone; the defaults already point the admin at http://localhost:3001 and the web app at http://localhost:3000.

Install, start the services and prepare the database

pnpm setup

pnpm setup runs four steps in order: pnpm install, pnpm infra:start, pnpm db:migrate and pnpm db:seed.

  • infra:start runs docker compose up -d --wait for postgres, pgbouncer, mailpit and minio.
  • The Postgres container runs apps/database/docker/postgres-init.sql on first start, which creates the migration_owner, auth_runtime, app_runtime, worker_runtime and function_owner roles.
  • db:migrate applies the SQL files in apps/database/migrations/ (0000_baseline through 0003_user_admin_mcp) through the direct connection (DATABASE_DIRECT_URL) and records a SHA-256 checksum for each one in public.nextbase_migrations. Editing an already applied migration is a hard failure.
  • db:seed creates an admin@nextbase.local user with the admin role, the acme workspace (Acme Inc.) owned by that user and a Launch project.

You cannot sign in as the seeded admin

The seed inserts the user row directly, without a password or any other credential. It exists so the seeded workspace has an owner. Sign up with your own account below and grant it the admin role with pnpm admin:grant.

If an image can't be pulled

The Compose file pins postgres:18-alpine, edoburu/pgbouncer:v1.24.1-p0, axllent/mailpit:v1.27 and minio/minio:RELEASE.2025-09-07T16-13-09Z. If one of them is unavailable in your registry, infra:start waits and fails. See troubleshooting for how to update the tag or start a subset of services.

Start the web and admin servers

pnpm dev

pnpm dev runs turbo run dev --parallel, which starts every workspace package that has a dev script: the web server (tsx watch server.ts in apps/web, port 3000), the admin server (PORT=3001 tsx watch server.ts in apps/admin) and the React Email preview server from apps/email.

The admin app and the email preview both default to port 3001

apps/admin listens on 3001 and apps/email's dev script also passes --port 3001. Whichever starts second fails to bind. If you need both at once, start them individually: pnpm --filter @nextbase/web dev and pnpm --filter @nextbase/admin dev in two terminals, and run the preview server separately with pnpm --filter @nextbase/email exec email dev --dir src/templates --port 3002.

Open these addresses:

ServiceAddress
Web applicationhttp://localhost:3000
Admin applicationhttp://localhost:3001 (redirects to /app-admin, which asks you to sign in)
Mailpit inboxhttp://localhost:38025
MinIO consolehttp://localhost:39001 (user nextbase, password from S3_SECRET_ACCESS_KEY in .env.example)

Start the outbox worker

Verification and password reset emails are written to app.outbox_jobs and sent by a separate process. Without it, no email reaches Mailpit. In another terminal:

pnpm --filter @nextbase/web worker

This runs tsx watch worker.ts with NEXTBASE_WORKER_MODE=daemon and polls the outbox as the worker_runtime role. Keep it running while you develop.

Create your account and workspace

Open http://localhost:3000/sign-up, enter a name, email and a password of at least 8 characters. Email verification is required, so open Mailpit at http://localhost:38025, open the verification mail and follow the link. The kit signs you in after verification and sends you to /app.

Open Workspaces and create one. The form posts to /api/v1/workspaces, which creates the workspace, makes you its owner and records a workspace.created audit event inside an actor transaction. The overview page then lists it.

Grant yourself application admin

pnpm admin:grant -- you@example.com

This runs apps/database/src/grant-admin.ts, which sets role = 'admin' on your Better Auth user through the direct connection and fails if the email doesn't exist. Sign out and back in, then open http://localhost:3001/login, sign in with the same email and password, and you land on /app-admin. See authentication for what the role controls.

Check that everything works

pnpm db:check          # roles, forced RLS and function grants
pnpm verify            # format check, lint, typecheck, unit tests, production build
pnpm test:integration  # PostgreSQL, RLS and impersonation tests through PgBouncer

pnpm verify is what CI runs. The integration suites in apps/database, apps/web and apps/admin need the Docker services running and the migrations applied; they refuse to run against a database that isn't on localhost. TESTING.md in the repository has the test policy.

Stop and reset

pnpm infra:stop    # docker compose down, keeps the volumes
pnpm infra:reset   # docker compose down -v, then docker compose up -d --wait
pnpm db:migrate    # after a reset
pnpm db:seed

infra:reset deletes the local PostgreSQL and MinIO volumes. It never touches a remote database.

Ports

All local ports are set in .env.example and read by docker-compose.yml. Change POSTGRES_PORT, PGBOUNCER_PORT, SMTP_PORT, MAILPIT_UI_PORT, MINIO_API_PORT or MINIO_CONSOLE_PORT in .env when another kit already uses the defaults, and export the matching connection URLs so the apps follow. The web server port is PORT (default 3000); if you change it, change APP_BASE_URL, TRUSTED_ORIGINS and the admin app's WEB_APP_URL as well. The admin app's dev script hard-codes PORT=3001; edit apps/admin/package.json and ADMIN_APP_URL together if you move it.

TanStack + Neon

What the TanStack + Neon starter ships, what you need to run it, and where to go next.

Environment variables

Every variable in the TanStack + Neon starter's env files, what it does and where the value comes from.

On this page

Clone the repositoryEnable pnpm through corepackCreate the env fileInstall, start the services and prepare the databaseStart the web and admin serversStart the outbox workerCreate your account and workspaceGrant yourself application adminCheck that everything worksStop and resetPorts