React hooks — overview
The client-side hook surface, grouped by purpose.
The web side of a Voltro app talks to API apps through React hooks. Data hooks are keyed by API name and RPC tag; routing hooks are provided by @voltro/web.
App code should reach for the typed binding rather than the tag-taking hooks directly: createHooks(apiName) takes the api's generated AppProcedures map and returns useSubscription / useMutation / useAction whose tag is a literal union and whose input and output types are inferred — so a typo'd tag is a compile error and the result needs no annotation. Bind it once per api in src/lib/api.ts. The tag-taking forms documented below are the primitive underneath, for code that only learns the tag at runtime.
Data Hooks
| Hook | Purpose |
|---|---|
createHooks |
Bind the typed hook surface for one api — the recommended app-facing entry point. |
useSubscription |
Subscribe to a reactive query (*.query.ts). |
useMutation |
Run an atomic write (*.mutation.ts). |
useAction |
Run a unary non-transactional action (*.action.ts). |
useWorkflow |
Start, cancel, resume, or signal a durable workflow (*.workflow.tsx). |
useWorkflowSignal |
Focused signal sender, for approval buttons that don't also start workflows. |
useWorkflowUpdate |
Focused tracked update — waits for the workflow handler's result. |
useWorkflowRun |
Subscribe to one workflow run's reactive status row. |
useWorkflowRuns |
Subscribe to a bounded/filterable workflow run list. |
useWorkflowRunSteps |
Subscribe to one run's checkpointed step timeline. |
useWorkflowRunEvents |
Subscribe to one run's lifecycle/timer/signal event timeline. |
useWorkflowDomainEvents |
Subscribe to the domain events a workflow emitted (the business-event timeline). |
useWorkflowEventDeliveries |
Subscribe to delivery attempts/outcomes for those emitted events. |
useWorkflowRunState |
Aggregates run + steps + events into one { status, currentStep, waitingFor, … } plus cancel/resume/signal/update. |
useAgentStream |
Consume a one-shot element stream (*.stream.ts). |
useAgent |
Convenience wrapper for transient AI streams. |
Routing Hooks
| Hook | Purpose |
|---|---|
useLocation |
Current pathname and route state. |
useParams |
URL params from [name] segments. |
useNavigate |
Programmatic navigation. |
usePrefetch |
Trigger loader-data prefetch. |
useLoaderData |
Page loader output. |
Server / Context Hooks
| Hook | Purpose |
|---|---|
useServerRequest |
Request snapshot during SSR and hydration-sensitive client code. |
Schema-driven UI Hooks
The headless primitives that derive UI from a descriptor's Schema. Reach for these before hand-rolling a form, a table, or a picker — full guide in Schema-driven UI.
| Hook | Purpose |
|---|---|
useFormBinding |
Bind a form to a MUTATION — fields + validation from its input Schema; a server ValidationError({ field }) routes to that field. |
useFormField |
One field of the enclosing binding — value, blur, the display-gated error, a11y props. Re-renders that field alone. |
useFormBindingContext |
The binding a <FormBindingProvider> (or <AutoForm>) mounted above — for a widget kit that needs the form itself, not one field. |
useDataTable |
Bind a table to a QUERY — live rows, columns derived from the output Schema, sort/filter/pagination. |
useQueryFilters |
Filter controls derived from a query's INPUT Schema (the read-side mirror of a form). |
useQueryField |
Query-bound picker — a debounced search term drives a live subscription. |
useFormSkeleton / useTableSkeleton |
Placeholders shaped like the REAL data, from the same Schema. |
useAsyncValidation |
Live server-side validation (uniqueness, cross-row) over a query binding. |
useDebounced |
Debounce a value (search, filter, validation input). |
useRecord |
One live record from a "get" query, normalized (array → first row). |
useValidationMessages |
The app-wide validation-message resolver from <ValidationMessagesProvider>, or undefined when none is mounted — for a widget kit that resolves message ids itself. |
Files, Permissions, and Client Utilities
| Hook | Purpose |
|---|---|
useUpload |
File upload with progress + cancel, on every storage provider. Not base64 → action. |
usePresenceChannel |
One presence wire for local-first: the peer roster plus a publish/subscribe pair for ephemeral payloads (cursors, typing), riding the existing presence lane rather than a second socket. Room-scoped — a mismatched room throws instead of delivering across rooms. |
useCan |
Scope/RBAC UI gate, over <PermissionProvider>. Lives in @voltro/client — scopes are a framework concept, so gating a button needs no rbac dependency. |
useCanAny |
OR variant of useCan — true when the subject holds AT LEAST ONE of the required scopes. |
usePermissions / <PermissionProvider> |
The current subject's scope set, fed once from your session query — the source useCan reads. Gates UI on the SAME scope strings the server checks. |
useResourceCan / useResourceCans |
Per-RESOURCE (ReBAC) gate, reactive — one resource or many in a single subscription. |
useDerived |
Dependency-tracked derived value from reactive sources. Replaces hand-maintained useMemo dep arrays. |
useWindowedSubscription |
Subscribe to the VISIBLE window of a huge list, not the whole table. |
useOutbox |
Queue mutations offline, replay in order on reconnect. |
useUndoLog / useUndo |
Client controller for the server-persisted undo stack. |
usePreview |
Mutation dry-run — run the real handler in a rolled-back transaction. |
useProvenance |
"Why is this value here?" — lineage lookup for a field. |
useOnRpcError / reportClientError |
Subscribe to the rpc error bus; report a client error to the server. |
useSubscriptionHealth |
Which of an api's calls are currently REFUSED — a refused subscription never retries and reads as loading. |
useTracking |
Fire mount/unmount + interaction tracking events. |
useCapabilityManifest |
The api's capability manifest (procedures + tables + schemas), fetched once. |
useRefreshSubscriptions |
Force-refresh live subscriptions (e.g. after an out-of-band change). |
AI Hooks
| Hook | Purpose |
|---|---|
useAgentChat |
Full chat surface over an *.agent.tsx (messages + send + streaming). |
useResumableAgentStream |
Agent stream that survives reload/reconnect. |
useDataCopilot |
Bind a data-copilot action by api name + tag. |
Plugin and Local-First Hooks
Shipped by an installed plugin or by @voltro/local-first, not by
@voltro/client — the import path is the package, and each takes the api name
as its last argument (default 'app'). The rest of the surface reads exactly
like the hooks above.
| Hook | Package | Purpose |
|---|---|---|
useWebPush |
@voltro/plugin-notifications/web |
Web-push permission flow, service-worker registration and subscribe/unsubscribe — { status, error?, subscribe, unsubscribe }, where status distinguishes unsupported / denied / subscribed for THIS browser. |
useComments |
@voltro/plugin-comments/web |
The live threads on one anchor plus every action on them (create, edit, resolve, remove, react, markRead) and the unread badge count. |
useThread |
@voltro/plugin-comments/web |
One thread by id — a projection over the same live list, so it opens no second subscription. |
useMentionSearch |
@voltro/plugin-comments/web |
@-mention autocomplete over the app-declared, tenant-filtered directory. |
useCrdtText |
@voltro/local-first/react |
A collaborative text field bound to one crdtText() cell — merged text, minimal-span edits, the offline queue and synced. |
useCrdtDoc |
@voltro/local-first/react |
The sync half of a crdtDoc() column — one SyncClient + one live CRDT document per cell, with the echo guard that keeps a folded remote update from being pushed back. Hands the document to useCrdtEditor. |
useCrdtEditor |
@voltro/local-first/editor |
A collaborative rich-text editor over a crdtDoc() column — one Tiptap instance bound to the shared document, carets bridged over an injected transport. |