Instant sync.
A new way to build apps with distributed state.
Cross-device sync
Real-time multiplayer
Team/social features
Built-in permissions
Cloud sync & storage
On-device storage
Instant UI updates
E2EE & signatures
Hard things are easy now.
Jazz is an open-source toolkit that replaces APIs, databases and message queues with a single new abstraction:
“Collaborative Values” — distributed state with secure permissions built-in.
Features that used to take months to build now work out-of-the-box.
First impressions…
A chat app in 84 lines of code.
app.tsx
tsx
import {CoMap ,CoList ,co ,Group ,ID } from "jazz-tools";import {createJazzReactContext ,DemoAuth } from "jazz-react";import {createRoot } from "react-dom/client";import {useIframeHashRouter } from "hash-slash";import {ChatScreen } from "./chatScreen.tsx";export classMessage extendsCoMap {text =co .string ;}export classChat extendsCoList .Of (co .ref (Message )) {}constJazz =createJazzReactContext ({auth :DemoAuth ({appName : "Jazz Chat" }),peer : `wss://mesh.jazz.tools/?key=you@example.com`});export const {useAccount ,useCoState } =Jazz ;functionApp () {const {me ,logOut } =useAccount ();constcreateChat = () => {constgroup =Group .create ({owner :me });group .addMember ("everyone", "writer");constchat =Chat .create ([], {owner :group });location .hash = "/chat/" +chat .id ;};return <div className ="flex flex-col items-center justify-between w-screen h-screen p-2 dark:bg-black dark:text-white"><div className ="rounded mb-5 px-2 py-1 text-sm self-end">{me .profile ?.name } · <button onClick ={logOut }>Log Out</button ></div >{useIframeHashRouter ().route ({'/': () =>createChat () as never,'/chat/:id': (id ) => <ChatScreen chatID ={id asID <Chat >} />})}</div >;}createRoot (document .getElementById ("root")!).render (<Jazz .Provider ><App /></Jazz .Provider >);
chatScreen.tsx
tsx
import {ID } from 'jazz-tools';import {Chat ,Message ,useCoState } from './app.tsx';export functionChatScreen (props : {chatID :ID <Chat > }) {constchat =useCoState (Chat ,props .chatID , [{}]);returnchat ? <div className ='w-full max-w-xl h-full flex flex-col items-stretch'>{chat .length > 0?chat .map ((msg ) => <ChatBubble msg ={msg }key ={msg .id } />): <div className ='m-auto text-sm'>(Empty chat)</div >}<ChatInput onSubmit ={(text ) => {chat .push (Message .create ({text }, {owner :chat ._owner }));}} /></div > : <div >Loading...</div >;}functionChatBubble (props : {msg :Message }) {constlastEdit =props .msg ._edits .text ;constalign =lastEdit .by ?.isMe ? 'items-end' : 'items-start';return <div className ={`${align } flex flex-col`}><div className ='rounded-xl bg-stone-100 dark:bg-stone-700 dark:text-white py-2 px-4 mt-2 min-w-[5rem]'>{props .msg .text }</div ><div className ='text-xs text-neutral-500 ml-2'>{lastEdit .by ?.profile ?.name }{' '}{lastEdit .madeAt ?.toLocaleTimeString () }</div ></div >;}functionChatInput (props : {onSubmit : (text : string) => void }) {return <input className ='rounded p-2 border mt-auto dark:bg-black dark:text-white border-stone-300 dark:border-stone-700'placeholder ='Type a message and press Enter'onKeyDown ={({key ,currentTarget :input }) => {if (key !== 'Enter' || !input .value ) return;props .onSubmit (input .value );input .value = '';}} />;}
Collaborative Values
Your new building blocks.
Based on CRDTs and public-key cryptography, CoValues...
- Can be read & edited like simple local JSON state
- Can be created anywhere, are automatically synced & persisted
- Always keep full edit history & author metadata
- Automatically resolve most conflicts
Bread-and-butter datastructures
CoMap
- Collaborative key-value map - Possible values: - Immutable JSON & other CoValues
CoList
- Collaborative ordered list - Possible items: - Immutable JSON & other CoValues
CoPlainText
& CoRichText
Coming soon
- Collaborative plain-text & rich-text - Gracefully prevents most editing conflicts - Rendered as markdown, HTML, JSX, etc.
CoStream
- Collection of independent per-user items streams:
- Immutable JSON & other CoValues
- Great for presence, reactions, polls, replies etc.
First-class files & binary data
BinaryCoStream
- Represents a file or live binary stream - Can be referenced and synced
like any other CoValue - Can easily be converted from/to browser
Blob
s <input type="file"/>
->BinaryCoStream
->Blob
->BlobURL
ImageDefinition
- Represents multiple resolutions of the same image - Can be progressively loaded, including super fast blur preview & image size info
Secure permissions, authorship & teams
Group
- A scope where specified accounts have roles (
reader
/writer
/admin
). - A
Group
ownsCoValues
, with access right determined by group roles. - Accounts can be added to groups directly or using shareable invite secrets.
Account
- Represents a single user and their signing/encryption keys.
- Has a private account root and a public profile
- Can contain arbitrary app-specific data
The Jazz Toolkit
A high-level toolkit for building apps around CoValues.
Supported environments:
- Browser (sync via WebSockets, IndexedDB persistence)
- React
- Vanilla JS / framework agnostic base
- React Native Coming soon
- NodeJS (sync via WebSockets, SQLite persistence) Coming soon
- Swift, Kotlin, Rust Coming later
Auto-sub
Let your UI drive data-syncing.
- Load and auto-subscribe to deeply nested
CoValues
with a reactive hook (or callback). - Access properties & metadata as plain JSON. - Make granular changes with simple mutators. - No queries needed, everything loads on-demand:
profile?.tweets?.map(tweet => tweet?.text)
Cursors & carets
Ready-made spatial presence.
- 2D canvas cursors Coming soon
- Text carets Coming soon
- Element-based focus-presence Coming soon
- Scroll-based / out-of-bounds helpers Coming soon
Auth Providers
Plug and play different kinds of auth.
- DemoAuth (for quick multi-user demos)
- WebAuthN (TouchID/FaceID)
- Auth0, Clerk & Okta Coming soon
- NextAuth Coming soon
Two-way sync to your DB
Add Jazz to an existing app.
- Prisma Coming soon
- Drizzle Coming soon
- PostgreSQL introspection Coming soon
File upload & download
Just use
<input type="file"/>
.- Easily convert from and to Browser
Blob
s - Super simple progressive image loading
Video presence & calls
Stream and record audio & video.
- Automatic WebRTC connections between
Group
members Coming soon - Audio/video recording into
BinaryCoStreams
Coming soon
Jazz Mesh
Serverless sync & storage for Jazz apps
To give you sync and secure collaborative data instantly on a global scale, we're running Jazz Mesh. It works with any Jazz-based app, requires no setup and has straightforward, scale-to-zero pricing.
Jazz Mesh is currently free — and it's set up as the default sync & storage peer in Jazz, letting you start building multi-user apps with persistence right away, no backend needed.
Learn more about Jazz Mesh