Installation
Get the TanStack template and its local D1 database running.
This guide takes a fresh copy of the template to a local Worker at
http://localhost:3000.
Prerequisites
- Node.js 22 LTS — recommended for the template's Vite 7 toolchain.
- pnpm — the package manager used by the repository.
- A Cloudflare account — required for remote D1/R2 setup and deployment, but not for the first local boot.
- Wrangler — already included as a dev dependency. Run it through
pnpm wrangler; a global install is unnecessary.
You do not need local PostgreSQL. Cloudflare D1 runs locally through the Worker development environment (Miniflare).
Setup
Create the local environment file
cp .env.example .envSet at least:
BETTER_AUTH_SECRET=replace-with-a-random-secret
BETTER_AUTH_URL=http://localhost:3000Generate a secret with openssl rand -base64 32. Under pnpm dev, the
Cloudflare Vite plugin makes .env available to both Vite (VITE_* through
import.meta.env) and the local Worker runtime. .dev.vars is only an optional
fallback if you run wrangler dev directly.
See Environment Variables before enabling OAuth, email, payments, AI, or remote D1 tooling.
Initialize local D1
The repository already includes a migration in drizzle/. Apply it to the
local Miniflare database:
pnpm db:migrate:localIf you changed the schema or started from a copy with an empty drizzle/
directory, generate and review a migration first:
pnpm db:generate
pnpm db:migrate:localThis does not touch remote D1. Do not use drizzle-kit push; the template uses
reviewed SQL migrations.
Verify the installation
- The homepage renders at
http://localhost:3000. - Registration creates a row in local D1 without a missing-table error.
- The app reaches the registration-success page.
- With Resend configured, the verification email arrives and its link works.
- After verification and login,
/dashboardopens.
Email verification is required. Without RESEND_API_KEY, the email helper
returns a failed send result, so registration may complete but the message is
not delivered and the account cannot finish the normal login flow. Configure
Email or deliberately relax verification for local-only
development.
Package scripts
| Command | Purpose |
|---|---|
pnpm dev | Start Vite on port 3000 with the local Worker runtime |
pnpm build | Build the production Worker and client assets |
pnpm preview | Preview the Vite production build |
pnpm deploy | Build, then deploy with Wrangler |
pnpm test | Run the Vitest suite once |
pnpm check | Run Biome lint and formatting checks |
pnpm lint | Run Biome lint diagnostics |
pnpm format | Run the Biome formatter |
Database and Wrangler scripts
| Command | Purpose |
|---|---|
pnpm db:generate | Generate SQL in drizzle/ from the Drizzle schema |
pnpm db:migrate:local | Apply migrations to local Miniflare D1 |
pnpm db:migrate | Apply migrations to the remote soar-tanstack D1 database |
pnpm cf-typegen | Regenerate Cloudflare binding types |
pnpm wrangler <command> | Run the repository's Wrangler CLI |
Common first-run failures
| Symptom | Likely cause | Fix |
|---|---|---|
no such table during registration | Local D1 is empty | Run pnpm db:migrate:local |
| Session or signing errors | BETTER_AUTH_SECRET is missing, a placeholder, or keeps changing | Generate a stable random value in .env |
| Cookies, redirects, or callbacks use the wrong host | BETTER_AUTH_URL does not match the browser origin | Use http://localhost:3000 locally |
| Verification/reset message never arrives | Resend is not configured | Set RESEND_API_KEY and a valid sender, or relax verification locally |
| GitHub/Google login fails | Provider credentials or callback URL are missing | Configure the provider or hide its button |
