Why Jazz / Comparisons
See what sets Jazz apart, how it compares to the tools you might know, and what it changes for a team.For developers
Jazz is your whole data layer: database, sync, streams and files, running inside the backend you already have.
Without it, that layer is usually assembled by hand: a traditional database for tables, a blob provider for files, a stream or pub/sub service for chat, presence and agent output, and a sync layer so screens update live and keep working on a flaky connection. Each piece has its own client, its own idea of who the user is and its own permission rules, and your team writes and maintains the glue that keeps them consistent.
With Jazz:
- Your app and its data live together. Jazz runs inside your backend, so there's one less
vendor and one less service to run. Tables, relations and a typed client work the same in backend
and frontend. Jazz plugs into whatever auth your backend uses, and clients sync with your backend
over a same-origin endpoint (
/jazzby default) using your app's existing session. - Your API layer mostly disappears. Permissions are declarative, so browsers and API routes can run Jazz queries and transactions directly, and Jazz checks each one for the user making it. Backend code can act with full trusted access or as a specific user, so you only write endpoints for logic a policy can't express.
- Sync built in. Subscribe to any query and your UI stays current on its own: a feed, a dashboard or a shared list updates the moment someone adds, edits or removes a row. When a screen needs instant writes or offline support, switch that client to local-first, with the same schema, queries and policies.
- Streams and files in the same model. Files, streams and mergeable text live in Jazz too, so
they sync and follow your permissions like every other value. Edit metadata
(
$createdBy,$updatedAt, …), history, drafts and branches come with every row. - One set of permissions. Policies live next to your schema in TypeScript and apply the same way to backend code, thin clients, local-first clients, files and streams. They're verbose, but agents are good at writing and checking them.
Compared to
Supabase
| Jazz | Supabase | |
|---|---|---|
| In common | ||
| Relational data | Tables, typed columns, relations and indexes. | |
| Database, auth hooks and permissions in one | One system for data, access rules and a client SDK, with no API layer to hand-write. | |
| Realtime | Clients can subscribe to changes. | |
| Differences | ||
| Where it runs | Inside your own backend, so your app and its data live together | A separate hosted platform, or a self-hosted multi-service stack |
| Live updates | Query results stay up to date without manual reconciliation | A stream of row changes your client reconciles by hand |
| Permissions | Declarative permissions in TypeScript, next to the schema | Declarative policies in SQL, on Postgres tables |
| History, branches and mergeable text | ✓ | ✗ |
| Offline writes and instant local UI | ✓ | ✗ |
| Full Postgres and its extensions | ✗ | ✓ |
When to use Jazz. You want live queries, typed policies and collaboration features without running a database platform, and you want the option of offline-capable local-first clients later.
When to use Supabase. You need full Postgres and its extension ecosystem, or you want a mature hosted dashboard with auth, storage and functions included.
Postgres
| Jazz | Postgres | |
|---|---|---|
| In common | ||
| Relational model | Tables, joins, constraints and transactions. | |
| Open source | Run it yourself, wherever you like. | |
| Differences | ||
| Live queries | ✓ | ✗ |
| Permissions for end users | Built in, as declarative permissions | Your API layer, or declarative policies in SQL |
| Sync to browsers and devices | ✓ | ✗ |
| Migrations | Typed and generated from the schema | SQL you write, or a separate tool |
| Arbitrary SQL and analytics | ✗ | ✓ |
| Ecosystem | Young | Decades of tools, extensions and hosting options |
When to use Jazz. Your app needs users to see each other's changes live, with access rules enforced in one place, and you want less code to maintain: no API and sync layer of your own on top of a database.
When to use Postgres. You need arbitrary SQL, heavy analytics or a specific extension, or your data already lives there and many systems read it.
Plain SQLite
| Jazz | SQLite | |
|---|---|---|
| In common | ||
| Storage | Jazz builds on SQLite under the hood, using its speed, proven reliability and lightweight, portable storage. | |
| Runs anywhere | Server, browser and mobile. | |
| Differences | ||
| Sync between clients and server | ✓ | ✗ |
| Permissions | ✓ | ✗ |
| Live queries | ✓ | ✗ |
| Concurrent edits from many devices | Merged by Jazz | Your app's responsibility |
| Dependencies | The Jazz library | None |
When to use Jazz. You want sync, permissions, live queries or offline support for your data, whether one user writes it or many.
When to use SQLite. You want an embedded SQL database without sync, collaboration, auth or permissions built in.
Plain Durable Objects
| Jazz | Durable Objects | |
|---|---|---|
| In common | ||
| Unit of scale | Small stateful units close to users. | |
| SQLite underneath | Each unit keeps its state in SQLite. | |
| Differences | ||
| Data model | Tables and queries across all your data | Per-object state and storage you design |
| Transactions across units | ✓ | ✗ |
| Permissions and live queries | Built in | Custom code in each object |
When to use Jazz. You want to work with shared data through tables and queries, with permissions and live updates built in. Durable Objects work best when your app splits into isolated islands of state; Jazz gives you one database across many of them, with transactions across shards.
When to use plain Durable Objects. Your app is made of isolated pieces of shared state, such as game rooms or rate limiters, and you want to build that behaviour yourself.
Convex
| Jazz | Convex | |
|---|---|---|
| In common | ||
| Reactive queries | Clients see query results update as data changes. | |
| Typed schema | Schema and types in TypeScript. | |
| Differences | ||
| Where it runs | Inside your own backend | Convex's hosted service, or self-hosted |
| Queries | Declarative relational queries | Server functions you write and deploy |
| Permissions | Declarative policies, plus ordinary code in your own backend routes for rules too complex for a policy | Checks written inside each function |
| Offline writes with local-first clients | ✓ | ✗ |
| Server functions next to the data | Use trusted backend API endpoints in your main backend | ✓ |
When to use Jazz. You want to query shared data directly from your app, define permissions once, and add offline support where you need it.
When to use Convex. You want to build your app around server functions, with a hosted backend that clients connect to for updated data.
Zero
| Jazz | Zero | |
|---|---|---|
| In common | ||
| Synced query results | Clients get query results synced from the server and kept up to date. | |
| Client-side cache | Fast reads from data already on the device. | |
| Differences | ||
| Source of truth | Jazz itself | Your existing Postgres |
| Thin client with no local cache | ✓ | ✗ |
| Offline writes | ✓ | ✗ |
| History, branches and mergeable text | ✓ | ✗ |
| Permissions | One set of policies for backend, thin-client and local-first access | Defined in your Zero app code |
When to use Jazz. You're starting fresh, or you want a database with collaboration features, permissions built in and offline writes.
When to use Zero. Postgres is already your source of truth and you want to add synced queries in front of it.
Neon
| Jazz | Neon | |
|---|---|---|
| In common | ||
| Serverless | No database server to size or keep warm. | |
| Relational | Tables and queries. | |
| Live queries | Subscribe to a query and see its results update. | |
| Differences | ||
| Setting up live queries | Subscribe to any query from the client | Enable Realtime per branch, then write each query on your server, seal it per user and serve it from an endpoint |
| Writes | Clients write directly, checked by your policies | Through API routes you write, with optimistic updates wired up in the client |
| Permissions | Policies next to the schema, for reads and writes | Whatever your sealed queries and API routes enforce |
| Offline writes | ✓ | ✗ |
| Real Postgres | ✗ | ✓ |
| Branching dev databases | Drafts and branches on rows | Branch the whole database |
When to use Jazz. You want the database, sync, permissions and live queries as one system, without the server code that wires them together.
When to use Neon. You want managed serverless Postgres, with database branching for development.
TanStack DB
| Jazz | TanStack DB | |
|---|---|---|
| In common | ||
| Live queries on the client | Reactive queries that update the UI as data changes. | |
| Optimistic writes | The UI updates before the server confirms. | |
| Differences | ||
| Server and storage | Included | Your own backend and APIs |
| Permissions | ✓ | ✗ |
| Same queries on the backend | ✓ | ✗ |
| Works with an existing backend unchanged | ✗ | ✓ |
When to use Jazz. You want a database with sync and permissions built in, using the same queries and access rules across both frontend and backend.
When to use TanStack DB. You have a backend and APIs you're keeping, and want reactive client collections on top of them.
For engineering leaders
- Less code to maintain: no glue code for data access, sync or permissions.
- Fewer moving parts: live and collaborative features natively in Jazz, without a separate stack.
- Keep your existing auth: your backend passes each user's identity to Jazz, including roles and claims from your identity provider, and policies check them directly.
- Choose where it runs: run Jazz on your own infrastructure, bring your own cloud, or use Jazz Cloud.
- Licensing: MIT for unsharded Jazz; unlock sharding with an enterprise license.