add-db
Skill106 starsChanged 7 months agoMITView on GitHub
Wire Drizzle ORM into a pracht app for D1, PlanetScale, Neon, Supabase, Turso, Postgres, MySQL, or SQLite: driver, schema, migrations, and a typed client. Use for "add a database", "set up Drizzle", "wire D1", "add Postgres", "set up an ORM".
- Reads credentials
- Installs packages
2 other projects use a version of this.
Adopted by
Most recently taken up by
- flavien-ia/hypervibe-crafttheir own version, first seen Oct 25, 2026
- flavien-ia/hypervibe-harnesstheir own version, first seen Oct 23, 2026
Other versions2 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 2
- flavien-ia/hypervibe-craft★ 50same name
- flavien-ia/hypervibe-harness★ 50same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository33 other files it gives its agents.
- AGENTS.mdAGENTS.md
- add-authSkill
- add-capabilitiesSkill
- add-contentSkill
- add-i18nSkill
- add-imagesSkill
- add-observabilitySkill
- add-openapiSkill
- audit-a11ySkill
- audit-agent-surfaceSkill
- audit-authSkill
- audit-bundlesSkill
- audit-csrfSkill
- audit-depsSkill
- audit-headersSkill
- audit-islandsSkill
- audit-loadersSkill
- audit-redirectsSkill
- audit-secretsSkill
- audit-seoSkill
- audit-shellsSkill
- configure-isgSkill
- migrate-nextjsSkill
- pracht-debugSkill
- pracht-deploySkill
- pracht-scaffoldSkill
- pracht-test-apiSkill
- pre-deploySkill
- scaffold-e2eSkill
- scaffold-testsSkill
- tune-render-modeSkill
- typed-routesSkill
- upgrade-prachtSkill
The file
We split this skill into the rules it gives an agent
2 rules. About 0 are common, 0 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 32
Ask with AskUserQuestion, then cross-check against the project's adapter (pracht inspect build --json) and flag mismatches.
- Very specific: line 73
Read connection strings via serverEnv from @pracht/core/env/server, never process.env — it keeps the secret out of the client bundle and …
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Pracht Add Database (Drizzle)
Drizzle suits pracht because it is small, type-safe, and runs in both Node and
edge runtimes. This skill sets up the driver, schema, migration tooling, and a
client factory wired to the project's adapter. Never overwrite an existing
drizzle.config.ts, wrangler.toml, or package.json script — diff, merge,
and ask about collisions.
MCP: if pracht dev-mcp is registered, prefer its inspect_*, generate_*, doctor, and verify tools to the CLI.
pracht inspect build needs a prior pracht build.
Step 1: Pick the target
Ask with AskUserQuestion, then cross-check against the project's adapter
(pracht inspect build --json) and flag mismatches. On Cloudflare Workers,
TCP drivers (pg, postgres) need a Hyperdrive binding plus
compatibility_flags = ["nodejs_compat"] in the wrangler config; without
Hyperdrive, use an HTTP/WebSocket driver (Neon, PlanetScale, Turso) or D1.
| Provider | Driver import | Extra package | Runtimes |
| Cloudflare D1 | drizzle-orm/d1 | — (Workers binding) | Edge |
| Cloudflare Hyperdrive (Postgres) | drizzle-orm/postgres-js or node-postgres | postgres / pg | Workers (Hyperdrive + nodejs_compat) |
| PlanetScale | drizzle-orm/planetscale-serverless | @planetscale/database | Node + edge |
| Neon | drizzle-orm/neon-serverless or neon-http | @neondatabase/serverless | Node + edge |
| Supabase Postgres | drizzle-orm/postgres-js | postgres | Node; Workers via Hyperdrive |
| Turso (libSQL) | drizzle-orm/libsql | @libsql/client | Node + edge |
| Vanilla Postgres | drizzle-orm/node-postgres | pg + -D @types/pg | Node only |
| Vanilla MySQL | drizzle-orm/mysql2 | mysql2 | Node only |
| SQLite | drizzle-orm/better-sqlite3 | better-sqlite3 + -D @types/better-sqlite3 | Node only |
pnpm add drizzle-orm <driver-package>
pnpm add -D drizzle-kitStep 2: Schema
src/db/schema.ts — pgTable from drizzle-orm/pg-core, sqliteTable from
drizzle-orm/sqlite-core (D1 and SQLite), or mysqlTable from
drizzle-orm/mysql-core:
import { pgTable, serial, text, timestamp } from "drizzle-orm/pg-core";
export const users = pgTable("users", {
id: serial("id").primaryKey(),
email: text("email").notNull().unique(),
createdAt: timestamp("created_at").defaultNow().notNull(),
});Step 3: Client factory
Read connection strings via serverEnv from @pracht/core/env/server, never
process.env — it keeps the secret out of the client bundle and resolves per
adapter (https://pracht.resynapse.dev/docs/env). The shape depends on the runtime:
- Node, persistent process — a module-level singleton is fine, because
serverEnvworks at module top level there. - Edge with per-request context (Cloudflare, Vercel Edge) — read
serverEnvor the binding inside a factory. Workers env bindings only exist per request, so a module-level read bricks the worker at import time.
// src/db/client.ts — Postgres on Node
import { serverEnv } from "@pracht/core/env/server";
import { drizzle } from "drizzle-orm/node-postgres";
import { Pool } from "pg";
import * as schema from "./schema";
const pool = new Pool({ connectionString: serverEnv.DATABASE_URL });
export const db = drizzle(pool, { schema });For Cloudflare D1, register the Cloudflare context type once via the Register
augmentation. Keep the import: without it the file is a global script and the
declaration replaces @pracht/core's types instead of extending them.
// src/env.d.ts
import "@pracht/core";
declare module "@pracht/core" {
interface Register {
context: {
env: Env; // wrangler-generated bindings type, includes DB: D1Database
executionContext: ExecutionContext;
};
}
}The factory then needs no per-file generics:
import type { LoaderArgs } from "@pracht/core";
import { drizzle } from "drizzle-orm/d1";
import * as schema from "./schema";
export function getDb({ context }: Pick<LoaderArgs, "context">) {
return drizzle(context.env.DB, { schema });
}Without that augmentation, the inline generic must describe the full context —
LoaderArgs<{ env: { DB: D1Database }; executionContext: ExecutionContext }> —
because the context is { env, executionContext }, not the bindings object.
Step 4: drizzle.config.ts and scripts
process.env is fine in drizzle.config.ts: it runs under the drizzle-kit
CLI on Node, never inside the worker.
import { defineConfig } from "drizzle-kit";
export default defineConfig({
schema: "./src/db/schema.ts",
out: "./drizzle/migrations",
dialect: "postgresql", // or "sqlite" / "mysql"
dbCredentials: { url: process.env.DATABASE_URL! },
});D1 is the exception. It has no TCP endpoint, so drizzle-kit can only
generate migrations — applying goes through wrangler. Omit dbCredentials
entirely (add a driver: "d1-http" block with Cloudflare account/database/API
token only if you want drizzle-kit studio), and omit db:push: the
migrations-apply flow is the only supported path. Split local from remote so
the miniflare D1 can be iterated without touching production.
| Script | Non-D1 | Cloudflare D1 |
db:generate | drizzle-kit generate | drizzle-kit generate |
db:migrate | drizzle-kit migrate | wrangler d1 migrations apply <db-name> --local / --remote as db:migrate:local / db:migrate:remote |
db:push | drizzle-kit push (local dev only — prefer migrations beyond that) | omit |
db:studio | drizzle-kit studio | drizzle-kit studio |
<db-name> is the database_name from wrangler.toml/.jsonc.
Step 5: Bindings and env
Cloudflare D1 — merge the binding into
wrangler.toml/.jsonc.migrations_dirmust matchoutindrizzle.config.tsor wrangler will not find the SQL drizzle-kit emits:[[d1_databases]] binding = "DB" database_name = "my-app" database_id = "<id>" migrations_dir = "drizzle/migrations"- Node / Vercel — document
DATABASE_URLin.env.example, and add.env*to.gitignoreif it is missing.
Step 6: Use it in a loader
import type { LoaderArgs } from "@pracht/core";
import { db } from "../db/client"; // or getDb(args) on edge runtimes
import { users } from "../db/schema";
export async function loader(_args: LoaderArgs) {
const rows = await db.select().from(users).limit(20);
return { users: rows.map((u) => ({ id: u.id, email: u.email })) };
}Project explicitly — never spread DB rows into loader return values, since
everything returned crosses the wire (see /audit-secrets).
Step 7: Verify
pnpm db:generate
pnpm db:push # non-D1; or db:migrate once a migration exists
pnpm db:migrate:local # D1 — then db:migrate:remote when happy
pracht verify --json
pnpm testOn a fresh project pnpm test is a no-op and proves nothing about the DB
wiring. Suggest a loader smoke test that calls the Step 6 loader against a real
local DB and asserts the returned shape, or run /scaffold-tests to set that
up.
$ARGUMENTS
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

