bijection-svelte. Everything here
works in any Svelte app — SvelteKit, Vite + Svelte, or any other setup.
Make sure you’ve called setupBijection() in a root layout first — see
Overview.
Two clients
Bijection Svelte talks to your backend through two clients, and the one you use decides what’s available:BijectionClient is the live WebSocket client that setupBijection() opens — the
useQuery / useMutation / useAction helpers are thin Svelte wrappers around
it, and you can retrieve it directly with
getBijectionClient() / useBijectionClient(). BijectionHttpClient
is a stateless fetch-based client for single calls from server code or scripts
— see One-time calls. Live subscriptions and optimistic
updates are WebSocket-only, and optimistic updates apply to mutations only.
Queries
UseuseQuery() to subscribe to a Bijection query with automatic real-time
updates. When the data changes on the server, your component re-renders
automatically.
Options
initialData— pre-loaded data for SSR/hydration, avoids the loading state (see SSR with initialData)keepPreviousData— whentrue, keeps displaying the previous result while new data loads after args change
Skipping queries
You can conditionally skip a query by returning'skip' from the arguments
function. This is useful when a query depends on some condition, like
authentication state or user input.
isLoading will be false, error will be null,
and data will be undefined.
Mutations & Actions
UseuseMutation() and useAction() to get callable functions for your Bijection
mutations and actions. Both use the module-level singleton (getBijectionClient())
internally, so they work in .svelte components and plain .ts / .js
files — anywhere after setupBijection() has been called.
Optimistic updates
Optimistic updates let you update the UI immediately when a mutation is called, without waiting for the server to respond. Pass anoptimisticUpdate callback
in the mutation options at the call site to update the local query cache.
optimisticUpdate callback, use store.setQuery() to update the
local cache for a specific query. The arguments are:
- Query reference — the query to update (e.g.
api.user.get) - Query arguments — must match the arguments used by the active
useQuery()subscription - New value — the optimistic data to display immediately
Client access
getBijectionClient() — universal client access
getBijectionClient() retrieves the client from a module-level singleton. It
works anywhere — .svelte components, plain .ts utility files, service
layers, async callbacks — as long as setupBijection() has been called first.
This is the recommended way to access the client outside of the layout where
setupBijection() returns it directly.
useBijectionClient() — Svelte context alternative
useBijectionClient() retrieves the same client from Svelte context via
getContext(). It only works during component initialization — inside .svelte
files or code called synchronously from a component’s <script> block. Both
functions return the same BijectionClient instance.
Using mutations in utility files
useMutation() and useAction() work in plain .ts files too, since they use
the module-level singleton:
src/lib/services/tasks.ts
The
.svelte.ts file extension enables Svelte 5 runes ($state, $derived,
$effect) but does not make getContext() work outside components. If you
need the client in a plain .ts file, use getBijectionClient(), not
useBijectionClient().One-time calls
useQuery keeps a live subscription open. When you instead need a single result
with no ongoing binding — a SvelteKit load function, a form action, an endpoint,
or a one-off script — use the stateless
BijectionHttpClient, which runs
query / mutation / action over fetch with no WebSocket.
createBijectionHttpClient()
helper builds one with per-request auth wired in. The HTTP client supports
one-shot calls only — no subscriptions and no optimistic updates.
Mutations and actions have no “live” form to opt out of: useMutation() and
useAction() are already one-shot calls (thin wrappers over the WebSocket
client), so they cover writes in both reactive and non-reactive code.
Paginated queries
For queries that return large datasets, useusePaginatedQuery() to load
results incrementally. This hook manages cursor-based pagination automatically
and provides a loadMore function to fetch additional pages.
Options
initialNumItems(required) — number of items to load on the first pageinitialData— optional initial data for SSR/hydrationkeepPreviousData— whentrue, keeps previous results visible while loading new data after args change
'skip' from the arguments
function, just like with useQuery().
API reference
Functions and types exported frombijection-svelte:
Authentication exports (
setupAuth, useAuth, and related types) are
documented on the Authentication page.