Core Concepts

This page gives you a mental model for vibecode‑db at a glance—what each piece is for, how they fit, and the few rules that keep everything consistent across environments.


3.1 Client & Context

  • Client: the runtime interface you call (createClientdb.from(...).where(...).select(...)).
  • Context (ctx): passed to the adapter factory; contains your full DBSpec so adapters can initialize consistently.

3.2 Adapters

  • Bind the client to a runtime (Web WASM, Expo/React Native, Supabase).
  • The query API stays the same; only adapter wiring differs per environment.

3.3 Schema (vibecode‑db schema → Zod)

  • Define tables and columns with the schema DSL (defineSchema, vibecodeTable, column helpers).
  • The DSL generates a Zod bundle (runtime validation) and TypeScript types (compile‑time safety).

3.4 DBSpec

  • A typed object you pass to the client and adapters:
    { schema, relations, seed?, meta? }
  • schema (required): the Zod bundle from your DSL.
  • relations (required when you model FKs): graph inferred from your DSL.
  • seed (optional): boot data for local/dev.
  • meta (optional): adapter‑specific metadata.

3.5 Models, Tables & Columns

  • A model maps to a SQL table.
  • Columns are defined with helpers (int, text, boolean, datetime, …) and constraints (primaryKey, min, etc.).

3.6 Relations (one‑to‑one, one‑to‑many)

  • Use references with col to declare FKs in the schema DSL.
  • Example: user_id: references(col.integer('user_id'), () => db.tables.users.id)
  • Relations are used for nested reads and to inform adapters about integrity.

3.7 Query Builder (fluent chain)

  • Chain filters/modifiers first, then call .select(...) to execute.
  • Supports nested projection strings for relations:
    select('id, title, users(name)')

3.8 Migrations & Seeding (overview)

  • SQLite (Web/Expo): provide a string[] of SQL statements; adapters run them on startup.
  • Seeding: optional initial rows per table; useful for demos, tests, and rapid prototyping.

Put it together

  1. Define schema + relations → get Zod + types.
  2. Build a DBSpec.
  3. Create a client with an adapter per environment.
  4. Query using the same API everywhere.

That’s the core idea: one schema and one fluent API—portable across runtimes.