Core Concepts — Schema
The schema is your single source of truth. You define tables, columns, and relations once with the vibecode‑db schema DSL; the system generates a Zod bundle for runtime validation and TypeScript types for compile‑time safety. Every adapter reads from this same definition.
What the schema gives you
- Zod bundle: runtime validators derived from your DSL (
db.zodBundle). - Type inference: static types across queries, inserts, and updates.
- Relations graph: inferred from explicit FK declarations (used for nested reads).
- Consistency: one definition powers all environments (Web/Expo/Supabase).
Mental model
- Define tables & columns with the DSL (
defineSchema,vibecodeTable, column helpers likeint,text,boolean,datetime). - Declare foreign keys with
references+col(e.g.,user_id: references(col.integer('user_id'), () => db.tables.users.id)). - You obtain
db.zodBundleanddb.relations. - Build a DBSpec using these outputs and pass it to the client/adapter.
Example shape
1// db/schema.ts (illustrative)
2import { defineSchema, vibecodeTable, int, text, boolean, datetime, references, col } from '@vibecode-db/client'
3
4export const db = defineSchema({
5 users: vibecodeTable({
6 id: int().primaryKey(),
7 name: text().min(1),
8 email: text().email(),
9 }),
10 todos: vibecodeTable({
11 id: text().primaryKey(),
12 title: text(),
13 completed: boolean().default(false),
14 created_at: datetime(),
15 updated_at: datetime(),
16 user_id: references(col.integer('user_id'), () => db.tables.users.id),
17 }),
18})
19// Outputs -> db.zodBundle (validators), db.relations (FK graph)Keep the schema minimal and expressive: model constraints where they matter (e.g.,
min(1),email(),primaryKey()), and declare relations explicitly.
Derived types
- Input / Output models: inferred from your columns (e.g., insert vs select shapes).
- Select pickers: nested projection strings (e.g.,
'id, title, users(name)') map to typed results. - Partials: updates can infer partial shapes while preserving constraints where applicable.
Hand‑off to DBSpec
Use the schema outputs to assemble your DBSpec:
1{ schema: db.zodBundle, relations: db.relations, seed?, meta? }Pass that to createClient({ dbSpec, adapter }). Adapters use your schema/relations for migrations (SQLite), validation, and nested reads.
Summary
Define it once with the DSL → get validators, types, and relations for free → plug into any adapter. This keeps your model portable and your queries type‑safe across environments.