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

Install dependencies

From the template directory:

pnpm install

Create the local environment file

cp .env.example .env

Set at least:

BETTER_AUTH_SECRET=replace-with-a-random-secret
BETTER_AUTH_URL=http://localhost:3000

Generate 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:local

If 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:local

This 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, /dashboard opens.

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

CommandPurpose
pnpm devStart Vite on port 3000 with the local Worker runtime
pnpm buildBuild the production Worker and client assets
pnpm previewPreview the Vite production build
pnpm deployBuild, then deploy with Wrangler
pnpm testRun the Vitest suite once
pnpm checkRun Biome lint and formatting checks
pnpm lintRun Biome lint diagnostics
pnpm formatRun the Biome formatter

Database and Wrangler scripts

CommandPurpose
pnpm db:generateGenerate SQL in drizzle/ from the Drizzle schema
pnpm db:migrate:localApply migrations to local Miniflare D1
pnpm db:migrateApply migrations to the remote soar-tanstack D1 database
pnpm cf-typegenRegenerate Cloudflare binding types
pnpm wrangler <command>Run the repository's Wrangler CLI

Common first-run failures

SymptomLikely causeFix
no such table during registrationLocal D1 is emptyRun pnpm db:migrate:local
Session or signing errorsBETTER_AUTH_SECRET is missing, a placeholder, or keeps changingGenerate a stable random value in .env
Cookies, redirects, or callbacks use the wrong hostBETTER_AUTH_URL does not match the browser originUse http://localhost:3000 locally
Verification/reset message never arrivesResend is not configuredSet RESEND_API_KEY and a valid sender, or relax verification locally
GitHub/Google login failsProvider credentials or callback URL are missingConfigure the provider or hide its button

On this page