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

Installation

Clone the TanStack + Cloudflare D1 starter, migrate the local D1 database, start the web, admin and jobs Workers and create your first account.

This page gets the kit running on your computer. Nothing here needs a Cloudflare account; Wrangler runs D1, R2, Queues and Durable Objects locally.

Read getting started first if you are new to the v5 kits. Here is the kit-specific flow.

Clone the repository

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

If GitHub says the repository doesn't exist, check that you are signed in with the account that has access.

Use the right Node.js and pnpm

The repository pins Node.js 24 (.nvmrc) and pnpm@11.1.2 (packageManager in package.json). Let Corepack pick the pnpm version for you:

nvm use
corepack enable
pnpm install

pnpm install also builds esbuild, sharp and workerd, which are the only packages allowed to run build scripts.

Create the local secrets files

The web Worker, the admin Worker and the jobs Worker each read a .dev.vars file next to their wrangler.jsonc. Copy the examples only when the files are missing, so you keep any keys you already added:

[ -f apps/web/.dev.vars ] || cp apps/web/.env.example apps/web/.dev.vars
[ -f apps/admin/.dev.vars ] || cp apps/admin/.env.example apps/admin/.dev.vars
[ -f apps/jobs/.dev.vars ] || cp apps/jobs/.env.example apps/jobs/.dev.vars

The defaults are enough for local work. Leave RESEND_API_KEY in apps/jobs/.dev.vars empty so emails stay in the local inbox. Every variable is described on the environment variables page.

Apply the D1 migrations

pnpm db:migrate

This runs wrangler d1 migrations apply APP_DB --local using apps/web/wrangler.jsonc, which points at the SQL files in apps/database/migrations. Migration 0003_seed.sql is part of that run, so you also get the public blog and changelog content and a Nextbase Team seed user (team@nextbase.local) without a password. There is no separate seed step; pnpm db:seed only re-executes that same file.

The local database is stored under apps/web/.wrangler/state. The jobs Worker starts with --persist-to ../web/.wrangler/state and the admin app's Vite config points persistState at the same folder, so all three Workers share one local D1.

Start the dev servers

pnpm dev

Turborepo runs the dev script of every package in parallel, which starts four things:

ProcessPackageAddress
Web app (React Router dev server)@nextbase/webhttp://localhost:5173
Admin app (React Router dev server)@nextbase/adminhttp://localhost:5174
Jobs Worker (wrangler dev)@nextbase/jobshttp://localhost:8787/health
React Email template preview@nextbase/emailport 3001

Open http://localhost:5173. The admin app answers on http://localhost:5174 and redirects to /app-admin after you sign in there; pnpm admin:dev starts it on its own. The jobs health endpoint returns the pending, leased and dead outbox counts as JSON. The email preview shows the 41 templates; it is not the inbox.

The jobs Worker reaches the RealtimeRoom Durable Object through a script_name binding on the web Worker, which wrangler dev resolves through the local dev registry. Keep the web dev server running while the jobs Worker runs, otherwise realtime.invalidate jobs cannot reach the room.

Create your first account

Go to /sign-up on the web app, create an account and you will land on /verify-email?sent=1. The verification email is not sent anywhere. Because RESEND_API_KEY is empty, the jobs Worker writes the rendered message into the dev_email_inbox table in D1.

Read it with Wrangler from the repository root:

pnpm exec wrangler d1 execute APP_DB --local --config apps/web/wrangler.jsonc \
  --command "SELECT recipient, subject, html FROM dev_email_inbox ORDER BY created_at DESC LIMIT 1"

Copy the verification link from the html column into your browser. Verification signs you in and sends you to /onboarding, where you create your first workspace and accept the terms. You then land on /workspace/<slug>/home.

Add a project through the website so you have data to look at before you connect an agent.

Check that everything works

pnpm verify
pnpm test:integration
pnpm test:e2e

pnpm verify runs formatting, lint, type checks, unit tests and production builds for every package, including the admin app. pnpm test:integration runs the Workers and Miniflare D1 invariant tests in apps/web/test. pnpm test:e2e starts two servers, pnpm db:migrate && pnpm dev for the web app and pnpm --dir ../admin dev for the admin app, and runs the Playwright suite in apps/web/e2e against http://localhost:5173 and http://localhost:5174 with a single worker, because the tests share the persisted local database.

Make yourself an application admin

The seed does not create a reusable admin password. Sign up normally on the web app, verify, then grant the platform role to your own account:

pnpm exec wrangler d1 execute APP_DB --local --config apps/web/wrangler.jsonc \
  --command "UPDATE user SET role = 'admin' WHERE normalized_email = 'you@example.com'"

Then open http://localhost:5174/login, sign in with the same email and password, and you land on /app-admin. The admin app has its own session cookie, so signing in on the web app does not sign you in there. The web app has no /app-admin routes. The authentication page explains the roles.

Stop and reset

Press Ctrl+C in the terminal running pnpm dev. Local data stays in apps/web/.wrangler/state, which is ignored by git.

To start from an empty database, stop the dev servers, delete apps/web/.wrangler/state, and run pnpm db:migrate again. Local R2 objects and Durable Object storage live in the same folder, so this resets them too.

Migrations are forward-only

Never edit an applied migration. After changing the Drizzle schema in apps/database/src/schema, run pnpm db:generate, review the generated SQL, and add a new numbered file in apps/database/migrations. Then run pnpm db:migrate and pnpm test:integration.

If the local app opens but requests fail, check the troubleshooting page. For D1 the usual cause is a dev server that is no longer running or a migration that has not been applied.

TanStack + Cloudflare D1

What the TanStack + Cloudflare D1 starter is, what it ships with, and what you need before you start.

Environment variables

Every secret and Wrangler variable the web Worker, the admin Worker and the jobs Worker read, where it lives and where to get the value.

On this page

Clone the repositoryUse the right Node.js and pnpmCreate the local secrets filesApply the D1 migrationsStart the dev serversCreate your first accountCheck that everything worksMake yourself an application adminStop and reset