Framework Patterns
Side-by-side reference for React/Expo, Vue, Svelte, and Solid Jazz APIs.
Jazz provides framework-specific bindings for React/Expo, Vue, Svelte, and Solid. 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 | Solid |
|---|---|---|---|---|
| Provider | <JazzProvider config={config}> | <JazzProvider :client="client"> | <JazzSvelteProvider {client}> | <JazzProvider client={...}> |
| Query subscription | useAll(query) | useAll(query) | new QuerySubscription(query) | useAll(() => ({ query })) |
| DB access | useDb() | useDb() | getDb() | useDb() |
| Session | useSession() | useSession() | getSession() | useSession() |
| Client creation | createJazzClient(config) | createJazzClient(config) | createJazzClient(config) | createSolidJazzClient(...) |
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>import { type ParentProps } from "solid-js";
import { JazzProvider, createSolidJazzClient } from "jazz-tools/solid";
export function ProviderExample(props: ParentProps) {
const client = createSolidJazzClient(() => ({ appId: "my-app" }));
return (
<JazzProvider client={client} fallback={<p>Loading...</p>}>
{props.children}
</JazzProvider>
);
}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 { data: 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}import { For } from "solid-js";
import { useAll } from "jazz-tools/solid";
import { app } from "../schema.js";
export function QuerySubscriptionExample() {
const todos = useAll(() => ({ query: app.todos.where({ done: false }) }));
return <For each={todos.data ?? []}>{(todo) => <li>{todo.title}</li>}</For>;
}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, Svelte, and Solid, 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 });
}import { useDb, useSession } from "jazz-tools/solid";
import { app } from "../schema.js";
export function DbSessionExamples() {
const db = useDb();
const session = useSession();
async function addTodo(title: string) {
await db().insert(app.todos, { title, done: false });
}
void addTodo;
void session;
return null;
}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(); // ComputedRef<Session | null>const session = getSession(); // { current: Session | null }import { useDb, useSession } from "jazz-tools/solid";
import { app } from "../schema.js";
export function DbSessionExamples() {
const db = useDb();
const session = useSession();
async function addTodo(title: string) {
await db().insert(app.todos, { title, done: false });
}
void addTodo;
void session;
return null;
}