Framework Patterns
Side-by-side reference for React/Expo, Vue, and Svelte Jazz APIs.
Jazz provides framework-specific bindings for React/Expo, Vue, and Svelte. This page is a side-by-side reference — see Reading Data, Writing Data, and Sessions for full details.
API equivalents
| Concept | React / Expo | Vue | Svelte |
|---|---|---|---|
| Provider | <JazzProvider config={config}> | <JazzProvider :client="client"> | <JazzSvelteProvider {client}> |
| Query subscription | useAll(query) | useAll(query) | new QuerySubscription(query) |
| DB access | useDb() | useDb() | getDb() |
| Session | useSession() | useSession() | getSession() |
| Client creation | createJazzClient(config) | createJazzClient(config) | createJazzClient(config) |
Provider setup
Wrap your app in a provider to make the database available to every component.
export function ProviderExample() {
return (
<JazzProvider
config={{
appId: "my-app",
}}
fallback={<p>Loading...</p>}
>
<YourApp />
</JazzProvider>
);
}<script setup lang="ts">
import { createJazzClient, JazzProvider } from "jazz-tools/vue";
const client = createJazzClient({
appId: "my-app",
});
</script>
<template>
<JazzProvider :client="client">
<slot />
<template #fallback>
<p>Loading...</p>
</template>
</JazzProvider>
</template><script lang="ts">
import { createJazzClient, JazzSvelteProvider } from "jazz-tools/svelte";
const client = createJazzClient({
appId: "my-app",
});
</script>
<JazzSvelteProvider {client}>
{#snippet children({ db })}
<YourApp />
{/snippet}
{#snippet fallback()}
<p>Loading...</p>
{/snippet}
</JazzSvelteProvider>Query subscriptions
Subscribe to query results reactively. See Reading Data for the full API.
export function LiveQueryExample() {
const todos = useAll(app.todos.where({ done: false }));
// undefined = not yet connected; [] = connected, no rows; [...] = rows present
if (todos === undefined) return <p>Loading...</p>;
return (
<ul>
{todos.map((todo) => (
<li key={todo.id}>{todo.title}</li>
))}
</ul>
);
}<script setup lang="ts">
import { useAll } from "jazz-tools/vue";
import { app } from "../schema.js";
const todos = useAll(app.todos.where({ done: false }));
</script>
<template>
<li v-for="todo in todos ?? []" :key="todo.id">{{ todo.title }}</li>
</template><script lang="ts">
import { QuerySubscription } from 'jazz-tools/svelte';
import { app } from '../schema.js';
const todos = new QuerySubscription(
app.todos.where({ done: false }),
);
</script>
{#each todos.current ?? [] as todo}
<li>{todo.title}</li>
{/each}The ?? [] guard handles the undefined (not yet connected) case. See
Reading Data: The undefined loading state for patterns that depend on this signal.
In Vue and Svelte, the binding reconciles updates into the existing reactive array in place, so only fields that actually changed trigger re-renders. See Fine-grained updates for the full behaviour.
Accessing the database for writes
Get a handle to the database for inserts, updates, and deletes. See Writing Data for the full API.
export function DbAccessExample() {
// Must be called at component top level (rules of hooks)
const db = useDb();
async function addTodo(title: string) {
await db.insert(app.todos, { title, done: false });
}
void addTodo;
return null;
}// Must be called inside setup() or <script setup>
const db = useDb();
async function addTodo(title: string) {
await db.insert(app.todos, { title, done: false });
}// Callable anywhere — component, store, or utility module
const db = getDb();
async function addTodo(title: string) {
await db.insert(app.todos, { title, done: false });
}Session/user identity
Access the current user's session. See Sessions for details on authentication modes and identity linking.
export function SessionExample() {
const session = useSession(); // { user_id: string } | null
void session;
return null;
}const session = useSession(); // ShallowRef<{ user_id: string } | null>const session = getSession(); // { user_id: string } | null