migrate / convex
your reactive backend, on plain postgres.
convex pioneered the reactive-queries pattern briven adopts. the difference is the floor: convex stores your data in its own engine; briven stores it in plain postgres, which means pg_dump moves your whole product anywhere — convex, supabase, a self-hosted server, anywhere. same reactivity, no proprietary database.
what you're afraid of
will my useQuery hooks change?
no — briven's useQuery() matches convex 1:1. swap the import to @briven/client-react and your react tree compiles unchanged.
what happens to my data during the move?
we copy it. your convex deployment stays running and untouched. nothing on convex is deleted or modified — we read, we write a copy into briven, you keep both running in parallel until you flip writes.
how long will i be in a weird half-migrated state?
as long as you want. parallel-run is mandatory; cutover is your decision. we keep convex warm for 7 days after cutover as a one-click rollback target.
the conceptual mapping
your mental model survives the move. left column: what you call it in convex. right column: where it lives in briven.
| convex | briven |
|---|---|
| defineTable() with v.string() / v.number() / v.id() | briven schema DSL: text(), bigint(), text().references() |
| query() / mutation() / action() (multiple per file) | one default export per file under briven/functions/ |
| v.id("users") → fk to users table | text().references("users", "id") |
| ctx.db.query("notes").withIndex(...).collect() | ctx.db("notes").select().where({ ... }).orderBy(...) |
| useQuery("getNotes", args) on the client | useQuery("getNotes", args) — same signature |
| clerk / auth0 / convex auth | Better Auth (email + magic-link + OAuth) |
what the migration actually costs
ranked honestly: what comes for free, what we automate, what stays manual.
- free
data export — `npx convex export` already dumps every table to one zip; we read it directly.
- auto
schema translation — your TS schema in convex/schema.ts ports to briven schema DSL via our walker.
- auto
function translation — query / mutation / action handlers port to briven/functions/*.ts; the 80% pattern-matchable cases are translated automatically with diffs you review.
- manual
scheduler primitives — `ctx.scheduler.runAfter(...)` doesn’t exist in briven yet. we replace with a pg_cron entry or an action-driven sleep-and-poll.
- manual
auth cutover — convex auth doesn’t translate. we either preserve user ids during data import (so foreign keys still resolve) or force a one-time sign-in. you pick.
questions you actually have
- how much downtime?
- zero. your convex deployment serves traffic the entire migration. cutover is a DNS / client config flip you control. parallel-run lasts as long as you want.
- what about my custom server-side functions?
- we port each one and flag the cases we can’t auto-translate (custom 3rd-party SDKs, ctx.scheduler, ctx.storage). you review every translated file before it ships.
- can i go back to convex?
- yes, for 7 days after cutover. we keep your convex deployment in read-mirror sync with briven during that window. if you press rollback, your customers see no break.
- is briven really cheaper than convex?
- roughly. compare pricing at /pricing — briven's free tier is more generous for small projects, and the paid tier scales linearly on storage + invocations instead of convex's opaque bundling.
ready to start? no signup needed
leave us your email and we'll reach out within one business day. your convex stays untouched the entire time.
already got a briven account?
jump straight into the in-product wizard for a more detailed intake form — you can save progress and track status from your dashboard.