Skip to content
garden-coPublic

About

The data layer you own: Jazz is a database with tables, blobs, durable streams, collaborative rich text, permissions and more. It runs in your existing cloud as part of your backend.

Topics

Resources

Stars

231 stars

Watchers

3 watching

Forks

Latest commit

 

History

18,258 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Jazz

The data layer that you own.

Jazz is a relational database with tables, blobs, durable streams, collaborative rich text and more, all protected by declarative permissions. It runs in your existing cloud as part of your backend. Use live queries from your server or straight from your clients, including local-first apps.

Homepage · Docs · Quickstart · Discord · X

This is Jazz 2.0 (alpha), with an entirely new API. Looking for Classic Jazz?
LLMs: please follow the docs rather than what you learned about Jazz in training.

Start with your agent

Paste this into your coding agent. It works for a new project and for an app you already have: the agent asks what it needs and sets Jazz up in your backend.

Read https://jazz.tools/quickstart.md and use it to set up Jazz in this project.

Or have it run npm create jazz, which prints the same quickstart.

How it works

  • Part of your backend. Jazz is a library your server imports, wherever you deploy it, and keeps its data on that platform's storage. Its schema and permissions are the code you deploy, with no database server to run.
  • Live queries everywhere. Traditional clients call your API routes as usual. Browsers, mobile apps and backend clients can also live-sync on your own origin, querying straight from a component. Results stay up to date as anyone writes.
  • Local-first when you want it. Clients start thin. Switch one to local-first for offline use and instant reads: it runs the same Rust engine on the device, with the same queries.

1. Install in your backend and define a schema

// schema.ts
import { schema as s } from "jazz-tools";

const schema = {
  todos: s.table(
    {
      title: s.string(),
      done: s.boolean(),
      owner_id: s.uuid(),
    },
    {},
  ),
};

export const app = s.defineApp(schema);

export const permissions = s.definePermissions(app, ({ policy, session }) => {
  const mine = { owner_id: session.user };

  policy.todos.allowRead.where(mine);
  policy.todos.allowInsert.where(mine);
  policy.todos.allowUpdate.whereOld(mine).whereNew(mine);
  policy.todos.allowDelete.where(mine);
});
// jazz.server.ts
import { createJazz, sqlite } from "jazz-tools/backend";
import { app, permissions } from "./schema";

export const jazz = createJazz({
  app,
  permissions,
  // vercel() on Vercel, sqlite() locally and on your own servers
  store: sqlite({ path: "./jazz.db" }),
  // Better Auth, WorkOS or any custom auth:
  // return the user ID and permission-relevant claims, or null
  authenticate: (request) => getSignedInUser(request),
});
// app/jazz/[...path]/route.ts (Next.js; Hono, Express, Bun and Effect work too)
import { jazz } from "@/jazz.server";

// Sync for browsers, apps and agents, on your own origin
export const { GET, POST, DELETE } = jazz.next();

2. Query from anywhere

// app/api/todos/route.ts
import { jazz } from "@/jazz.server";
import { app } from "@/schema";

export async function GET(request: Request) {
  // Runs as the signed-in user: only their todos
  const db = await jazz.forReqUser(request);
  const todos = await db.all(app.todos.where({ done: false }));
  return Response.json(todos);
}
// OpenTodos.tsx
import { useAll } from "jazz-tools/react";
import { app } from "./schema";

export function OpenTodos() {
  // Live results, synced through /jazz with a thin client or fully local-first
  const { data: todos = [], db } = useAll(app.todos.where({ done: false }));

  return todos.map((todo) => (
    <label key={todo.id}>
      <input type="checkbox" onChange={() => db.update(app.todos, todo.id, { done: true })} />
      {todo.title}
    </label>
  ));
}

Setup guides

Contributing

Architecture specs

The authoritative architecture contracts live with the crates: crates/jazz/SPEC/ (data model, transactions, authorization, sync, queries, storage, API). Each chapter is structured as Overview (read this) / Details / Open Questions.

Prerequisites

  • Node.js (LTS) and pnpm 10+
  • Rust via rustup. The repository pins its toolchain in rust-toolchain.toml.
  • wasm-pack 0.13.1, which the WASM build (jazz-wasm, and so jazz-tools) shells out to. It is not installed by pnpm install. pnpm run ensure:rust-toolchain installs it, or run cargo install wasm-pack@0.13.1 --locked yourself.
  • A C compiler, because native builds compile the bundled SQLite from source (xcode-select --install on macOS, build-essential on Linux). WASM builds on macOS also need LLVM's archiver (brew install llvm).

Getting started

pnpm install
pnpm run ensure:rust-toolchain
pnpm build
pnpm test

Native artifact fingerprint values are generated build outputs. pnpm build, pnpm build:ci, and pnpm build:core build both native bindings and derive their matching TypeScript expectations before building consumers. Source-only checks, including React Native scaffold compilation, use declaration-only contracts; running Node/WASM consumers still requires the generated artifacts.

Building only jazz-tools

pnpm --filter jazz-tools build:runtime works from a fresh checkout on any supported host (Linux x64 and arm64, macOS). When the jazz-wasm package, the host's jazz-napi binding or their fingerprints are missing, it builds them (release profile) and stages the fingerprints before compiling. Inputs that are already present are reused. In CI (CI set) it fails instead, because workflows produce or download every native artifact explicitly.

pnpm run ensure:rust-toolchain adds the wasm32-unknown-unknown Rust target and installs wasm-pack if it is missing. It requires an existing Rust/rustup installation. React Native build dependencies have a separate bootstrap script: dev/scripts/install-jazz-rn-deps.sh.

The homepage and documentation are a self-contained Next.js application under docs/. Build them with pnpm build:vercel-docs; they do not need a Rust or React Native bootstrap.

Native builds compile the bundled SQLite from source on first build (cached afterwards by sccache).

Package versioning

jazz-tools, jazz-wasm, jazz-napi, jazz-rn, jazz-rn-ios, jazz-rn-android and create-jazz are configured as a Changesets fixed group for lock-stepped releases. Keep workspace links in source (workspace:*) and let pack/publish resolve concrete versions.

Fast local binding builds

Use pnpm --filter jazz-wasm build:fast for correctness-focused WASM work. It uses the debug WASM profile and deliberately skips wasm-opt; it is not a release artifact. pnpm --filter jazz-wasm build remains the optimized release build used by CI and publishing. dev/rebuild-artifacts.sh wasm-fast exposes the same path alongside the other local artifact rebuilds.

For Node/browser correctness tests, produce and seal the native artifacts in the checkout where the tests will run, then launch the admitted consumers:

pnpm build:correctness-artifacts
pnpm test:typescript-consumers

The producer seals fast-WASM and release-NAPI artifacts with their source identity and hashes. The consumer verifies that receipt, rebuilds Jazz Tools, and runs the Node/browser suites against the sealed artifacts. Source changes require another producer run. For focused suites, use node dev/gates/run-correctness-consumer.mjs -- <command> and rebuild Jazz Tools through that wrapper before testing after native production. Keep generated artifacts and producer manifests in their own checkout; artifacts-fresh.sh provides provenance diagnostics, while the consumer wrapper admits test inputs.

Alpha releases

Releases use alpha prerelease mode in .changeset/pre.json (mode: pre, tag: alpha). Add release intent with pnpm changeset. After release work settles on the release branch, the Changesets Release PR workflow runs ordinary pnpm release:version and updates changeset-release/release. All packages in the fixed group must advance together. Preserve prerelease state while preparing changesets and let versioning record consumed entries.

The release workflow dispatches Release preview (alpha) on the generated release branch. Before merging the release PR, verify its versions and release notes, and require a successful preview on that exact head and the required correctness and React Native device-acceptance receipts. The preview builds and verifies packed native/React Native artifacts and their consumers. If a preview run is missing, dispatch its workflow on changeset-release/release.

Merging the versioned release PR triggers the alpha publisher, which checks source versions and package payloads before publishing. Use the preview workflow for build-and-verify runs: it selects dry-run, whereas manual publisher dispatch defaults to publish. The release:version:alpha script creates snapshot versions; ordinary alpha release preparation uses release:version with prerelease mode active.

License

Jazz is MIT licensed.

About

The data layer you own: Jazz is a database with tables, blobs, durable streams, collaborative rich text, permissions and more. It runs in your existing cloud as part of your backend.

Topics

Resources

Stars

231 stars

Watchers

3 watching

Forks

Releases

Contributors

Languages