Database & Migrations
Define PostgreSQL schemas with Drizzle ORM in VitNode plugins, generate migrations, and execute queries.
VitNode uses PostgreSQL and Drizzle ORM. Plugins define typed schema files, compile them into SQL migrations, and query tables via c.get("db").
Quick start
1. Define the Schema
Create a database model in plugins/{plugin}/src/database/{table}.ts:
import { camelCase } from "drizzle-orm/pg-core"
export const reactions = camelCase.table.withRLS("reactions", (t) => ({
id: t.serial().primaryKey(),
itemId: t.integer().notNull(),
emoji: t.varchar({ length: 32 }).notNull(),
createdAt: t.timestamp().notNull().defaultNow(),
}))2. Query in an API Route
Access the typed Drizzle instance using c.get("db"):
import { buildRoute } from "@vitnode/core/api/lib/route"
import { reactions } from "@/database/reactions"
export const getReactionsRoute = buildRoute({
pluginId: "reactions",
route: {
method: "get",
path: "/",
responses: { 200: { description: "List of reactions" } },
},
handler: async (c) => {
const rows = await c.get("db").select().from(reactions)
return c.json(rows)
},
})3. Build & Apply Migrations
Build and migrate
bun run build:plugins && bun run db:migratepnpm build:plugins && pnpm db:migratenpm run build:plugins && npm run db:migratebuild:plugins compiles your TypeScript models and exports, and db:migrate updates PostgreSQL.
Migration Commands
| Command | Action |
|---|---|
pnpm db:generate | Inspects schema diffs and writes timestamped SQL migrations |
pnpm db:migrate | Applies pending migrations against the target database |
pnpm db:studio | Opens Drizzle Studio to inspect and edit database rows visually |
Content Engine Alternative
If your table represents an editorial entity (articles, FAQs, products), consider Content Engine to generate your Drizzle table, API routes, and AdminCP screens from one definition.