Database
Drizzle ORM and PostgreSQL setup in the Nuxt template.
The database layer is Integrated: Drizzle ORM on
PostgreSQL via node-postgres, with auth and payment schemas. Postgres + Drizzle
is the only wired path — the Prisma stub was removed.
Important files
| File | Role |
|---|---|
server/database/drizzle/client.ts | Creates the Drizzle client: drizzle(runtimeConfig.databaseUrl) |
server/database/index.ts | Re-exports the client (and is the schema entry for Drizzle Kit) |
server/database/drizzle/drizzle.config.ts | Drizzle Kit config (dialect, schema, migrations out dir) |
server/database/drizzle/schema/auth.ts | user, session, account, verification tables |
server/database/drizzle/schema/payment.ts | subscription, payment tables + enums |
server/database/drizzle/service/payment.ts | Small data-access helper (createPayment) |
server/database/drizzle/types.ts | drizzle-zod insert schema (PaymentInsertScheme) |
Client
// server/database/drizzle/client.ts
import { drizzle } from "drizzle-orm/node-postgres";
const runtimeConfig = useRuntimeConfig();
const db = drizzle(runtimeConfig.databaseUrl!);
export default db;Import it anywhere on the server as import db from "~~/server/database/drizzle/client".
Better Auth consumes the auth schema through its Drizzle adapter
(provider: "pg") in server/utils/auth.ts — see
Authentication.
Schema
The auth schema holds Better Auth's user, session, account, and
verification tables (the user table includes role and the admin plugin's
banned/banReason/banExpires fields).
The payment schema holds:
subscription— one row per user (userIdunique), withprovider,status, period dates, and trial fields.payment— one row per order, withamount,currency,status,provider, and a uniqueorderNo.
Both use Postgres enums (provider, order_status, subscription_status,
plan_interval). See Payments for how rows are written.
Migration workflow
This template uses a generate/migrate workflow (not push). Drizzle Kit reads
server/database/drizzle/drizzle.config.ts, which points schema at
server/database/index.ts, writes migrations to server/database/migrations,
and reads NUXT_DATABASE_URL from the Nuxt runtime config.
| Command | What it does |
|---|---|
npx drizzle-kit generate | Generate SQL migrations from the schema |
npx drizzle-kit migrate | Apply pending migrations |
npx drizzle-kit studio | Browse data in Drizzle Studio |
The template ships without a committed server/database/migrations folder —
your first generate creates it from the current schema. Commit the generated
SQL so deploys apply the same migrations.
Add a table or field
Edit the schema
Add or change a table in server/database/drizzle/schema/*.ts. Make sure it is
reachable from server/database/index.ts, since that file is the Drizzle Kit
schema entry.
Generate and apply
npx drizzle-kit generate
npx drizzle-kit migrateKeep Better Auth in sync
If you change auth tables, keep them compatible with Better Auth's expected columns. Prefer extending via the plugin/config rather than renaming core columns.
Production notes
drizzle(databaseUrl)uses anode-postgrespool. On serverless/edge platforms, pointNUXT_DATABASE_URLat your provider's pooled connection string to avoid exhausting connections.- Run migrations as part of your deploy pipeline against the production database before traffic hits new code.
NUXT_ORM_PROVIDERis reserved but onlydrizzleis implemented.
