Installation
Requirements
- Node.js
- npm
- OpenSSL for local secret generation
- Wrangler through the project dependency
- A Cloudflare account for remote D1 and deployment
Create A Project
Create a new app:
npm create vergekit@latest my-appInstall dependencies:
cd my-app
npm installLocal Runtime Secrets
Create local runtime secrets. The paste-free option copies the template and writes a fresh Better Auth secret:
cp .dev.vars.example .dev.vars && secret="$(openssl rand -base64 32)" && awk -v secret="$secret" 'BEGIN { done = 0 } /^BETTER_AUTH_SECRET=/ { print "BETTER_AUTH_SECRET=" secret; done = 1; next } { print } END { if (!done) print "BETTER_AUTH_SECRET=" secret }' .dev.vars > .dev.vars.tmp && mv .dev.vars.tmp .dev.varsOr copy the file and fill the secret manually:
cp .dev.vars.example .dev.varsGenerate a Better Auth secret:
openssl rand -base64 32Add it to .dev.vars:
BETTER_AUTH_SECRET=your-generated-secretLocal callback URLs usually stay in .dev.vars:
BETTER_AUTH_URL=http://localhost:4321Committed, non-secret app defaults live in wrangler.jsonc under vars. Use
.dev.vars only for local secrets or local-only overrides.
Database
Apply local D1 migrations:
npm run db:migrate:localRegenerate migrations after schema changes:
npm run db:generateOptionally create a verified local user with the admin role after migrations:
npm run init:adminThis writes directly to D1 with Wrangler and does not require npm run dev.
Local dev uses Wrangler/Miniflare-backed D1 state through the
Astro Cloudflare adapter; no separate Miniflare config is required after
npm install.
See D1 Setup for production database setup, Drizzle Studio notes, and alternate local or Cloudflare-hosted development database options.
Auth Routes
All routes are public until they opt into auth. Add protected exact paths or URL
prefixes in src/config/auth.ts, or check Astro.locals.isAuthenticated inside
a specific page or route handler.
See Route Authentication for middleware-protected and route-local examples.
Better Auth plugins are configured in src/auth/server.ts and
src/auth/client.ts. The admin plugin is already installed and configured for
the app role model. See Route Authentication for the
plugin files that usually need to change when adding or modifying Better Auth
plugins.
The default local email provider is console.
Use it for local setup when you only need links printed to the terminal:
EMAIL_PROVIDER=consoleFor full auth behavior with delivered verification and reset emails, configure a real provider before testing auth:
EMAIL_PROVIDER=resend
EMAIL_FROM="VK <noreply@example.com>"
RESEND_API_KEY=your-api-keyMailgun uses:
EMAIL_PROVIDER=mailgun
EMAIL_FROM="VK <noreply@example.com>"
MAILGUN_API_KEY=your-api-key
MAILGUN_DOMAIN=mg.example.comCloudflare Email uses the EMAIL binding from wrangler.jsonc.
See Email Sending for direct send examples, provider requirements, auth-email helpers, and testing notes.
Configuration
Editable app defaults and auth policy live in src/config. Runtime Worker
values live in wrangler.jsonc vars. Local secrets live in .dev.vars, and
deployed secrets live in Wrangler secrets.
See Configuration Guide for the full split.
Run
Start the dev server:
npm run devRun the full local check:
npm run verifynpm run verify runs type checks, linting, tests, and the production build.