Ferry
Examples

Build your own stack

Ferry is not a platform to move your app onto, and not a React library either: the client is plain TypeScript, for any JavaScript app. It is a set of pieces, and each one is a plug point with a small contract. Keep the database, the auth, the framework and the state library you already have; Ferry adds the sync between them.

The pieces

PieceWhat Ferry asks of itBuilt inYour own
Where the app readsget() and subscribe() on a query, sync.onStatusReact hooks, Zustand, Jotai, Legend-StateVue, Svelte, Solid, vanilla JS: your own bindings, in a few lines
Where the device keeps dataThree methods: load, write and clearIndexedDB, SQLite, MMKV, localStorage, memoryWrite a storage, proven by storageConformanceCases
Who the user isauth(request): a user id, or nullNone: it is always yoursAny session, cookie or token: Supabase, Firebase, Clerk, Better Auth, your own
Where the server runsfetch(Request), or toNodeHandler for Node's httpAny framework that speaks Request and ResponseNext.js, Hono, Express, NestJS, Fastify, Bun, Deno, Workers
Where the server keeps dataA ServerStore: transactions, rows and an ordered logPostgres and SQLite (pg, postgres.js, PGlite, Prisma, Drizzle, node:sqlite, bun:sqlite, better-sqlite3, a Durable Object's SQLite), and Cloudflare D1Another database, proven by serverStoreConformanceCases from ferrysync/testing

Each contract is small on purpose. The two with the most to get right, the device's storage and the server's store, come with a conformance kit: the same tests Ferry's own pass. A piece that passes them works with the rest.

Your stack, as a backend for your frontend

The usual shape is a backend for frontend: the app talks only to its local database, and your backend sits between the devices and the services you already pay for. Ferry runs inside that backend, on one route.

  • Supabase: Supabase's Postgres and Supabase Auth, with Ferry in your own route.
  • Firebase: Firebase Auth for the users, your own database for the synced data.

Your own pieces

When nothing built in fits, write the piece. Each guide shows the contract, a real implementation, and how to prove it:

Backends

The same server, mounted where your app already runs:

  • Next.js: a route handler of the same app, and on Vercel.
  • Hono: one line, on Node, Bun, Workers or Deno.
  • Express: toNodeHandler, body parsers and auth.
  • Node.js: node:http with nothing else, Fastify and Nest.
  • Bun: Bun.serve and bun:sqlite.
  • Cloudflare Workers: D1 through a Durable Object, or Postgres with a store per request.

Data that is not synced

Next to Ferry, for what lives only on a server:

A runnable app

The repository's examples/ folder holds a complete todo app: todo-server (Hono, Bun and bun:sqlite), todo-web (Vite and React) and the todo-schema they share. Run both with bun run example from the repository root.

On this page