Dev-only — not production auth, authorization, or infrastructureOpen source · built with Claude Code

The Supabase developer experience, running locally.

Fakebase mimics the developer-facing shape of Supabase, backed by an in-process kernel. Build prototypes at zero-setup speed anywhere @supabase/supabase-js runs, then export real Supabase SQL migrations and database.types.tswhen you're ready to ship.

$ pnpm add @byronwade/fakebase
lib/fakebase.ts
import { createClient, createMemoryKernel } from "@byronwade/fakebase";
import schema from "./fakebase/schema";

const kernel = createMemoryKernel(schema);
export const supabase = createClient("local", "dev-key", { kernel });

// Same call shape as @supabase/supabase-js:
const { data, error } = await supabase
  .from("posts")
  .select("*")
  .eq("published", true)
  .order("created_at", { ascending: false });

Zero setup

No Docker, no local Postgres. createMemoryKernel() or a .fakebase/ JSON folder and you're writing data.

Same API surface

from().select().eq(), auth, storage, realtime, rpc — the exact @supabase/supabase-js call shape.

First-class export

Generate supabase/migrations/*.sql, seed.sql, and database.types.ts that drop into a real project.

Honest capabilities

Unsupported features throw a structured CapabilityError instead of silently faking behavior.

Fast today, honest about tomorrow

Fakebase is designed to be thrown away. The point is to get you to a working prototype, then out of the way — on the exact contract you'll ship against.

01

Code against the contract

Write your app against the @supabase/supabase-js client shape — any framework, today, with no backend.

02

Pick your fidelity

Swap the kernel adapter — memory, JSON, SQLite, or real Postgres-in-WASM (pglite) — without touching app code.

03

Export & ship

Emit Supabase-compatible SQL, seeds, and types, verify against real Postgres, then swap createClient.

Why I built Fakebase

I kept hitting the same wall while prototyping — especially with AI in the loop. I wanted to move fast on a design and have the schema and migrations come along for the ride, instead of stopping to re-provision a database and hand-sync migrations every time the shape of an idea changed.

So Fakebase is the tool I wanted: spin up a Supabase-shaped backend in-process, iterate on a near‑launch‑ready prototype as fast as you (or your AI) can change your mind, and when it settles, export real migrations and types instead of rewriting them. Quick and easy for prototyping, honest about the path to production.

B

Byron Wade

Creator of Fakebase

Honest capability labels

Every Supabase-shaped API is labeled by how faithfully Fakebase reproduces it. No silent gaps.

AreaFidelityNotes
Database CRUD + filtersExactfrom().select().eq()… order / range / single
Generated typesExactdatabase.types.ts from schema IR
Migrations + SQL exportExactSupabase-compatible SQL + seed.sql
RPC (rpc / functions.invoke)CloseLocal function registry
Auth (password / OTP / sessions)CloseLocal GoTrue-shaped flows
Storage (buckets / objects / URLs)CloseLocal filesystem + signed tokens
Realtime (broadcast / changes)CloseIn-process pub/sub
RLS policiesPartialDev approximation — verify on real Postgres
OAuth / SSO / MFA / passkeysUnsupportedCapability-gated errors

Full method-by-method matrix lives in the docs.

The path to real Supabase is short

Five steps from local prototype to production-ready Supabase project.

  1. 1
    fakebase migrate export --supabase

    Write supabase/migrations/*.sql from your schema IR.

  2. 2
    fakebase seed export

    Generate supabase/seed.sql from local data.

  3. 3
    fakebase types gen

    Emit database.types.ts — identical shape to Supabase's generator.

  4. 4
    fakebase verify supabase

    Run the compatibility suite against a real Supabase stack.

  5. 5
    swap createClient

    Replace fakebase's createClient with @supabase/supabase-js. Done.