Hooks
API reference for @urun-sh/react hooks
API reference for the hooks exported from @urun-sh/react. Every hook is a thin, render-safe view over the core Session primitives (streams / docs / phase) — the session owns the state; hooks project it into React.
Public API at a glance
| Name | Description |
|---|---|
useApp() | The deployed app proxy configured by UrunProvider |
useUrunAuth() | The current auth context (mode + token resolver) |
useRequest(session, options?) | Single request/response over session.request (mutation-style) |
useCompletion(session, options?) | Streamed text completion over session.requestStream |
useChat(session, options?) | Multi-turn chat with streaming assistant messages |
useInputPresence(session, options?) | Continuous keyboard/mouse input over awareness presence |
useSessionDoc(session, key, selector?) | Reactive view of a named session doc |
useDocStore(session, key) | Zustand-style store bound to a session doc (selector-granular) |
useStreamMessages(session, name, options?) | Bounded tail of a named stream's data lane |
useSessionTrack(session, name) | Latest inbound MediaStreamTrack for a named stream |
useUrunAudioLevel(source, options?) | Audio level metering for a track/stream |
useSessionPhase(session) | The current SessionPhase, reactively |
useSessionWake(session) | Live "waking (Ns)" view of the pre-live wait |
useSessionEndsAt(session) | The session deadline (Date | null) |
useSessionIdle(session) | The server-raised inactivity warning, or null |
useActivation(session, streamName?) | First-media activation progress for a named stream |
useUrunPrewake(options) | Advisory scale-to-zero warm-up ping while a page is mounted |
For patterns and narrative, see React Providers and Session lifecycle.
useApp()
function useApp(): ReactAppReturns the deployed app proxy. Each property is a deployed Python function; calling it returns a render-safe Session. Must be used inside a UrunProvider.
import { useApp, useSessionTrack } from '@urun-sh/react'
function Player() {
const app = useApp()
const session = app.generate({ prompt: 'a sunset' }) // render-safe
const track = useSessionTrack(session, 'video')
useEffect(() => {
if (track && ref.current) ref.current.srcObject = new MediaStream([track])
}, [track])
return <video ref={ref} autoPlay muted />
}useApp() memoizes by function name + args: the same app.generate(args) during re-renders reuses one session. session.stream(name) and session.doc(name) return stable, render-safe handles. The session surface matches the App reference.
useUrunAuth()
function useUrunAuth(): UrunAuthContextValueReturns the auth context established by the active auth bridge (UrunWorkOSProvider, UrunAuthProvider, or UrunJwtProvider). Use it to read the current auth mode or trigger a token refresh; most apps never call it directly because UrunProvider consumes it for you.
useRequest()
function useRequest<TRes, TReq>(session, options?: UseRequestOptions): UseRequestResult<TRes, TReq>Single request/response calls over session.request, shaped like react-query's useMutation: { mutate, mutateAsync, data, error, isPending, reset }. Each call gets its own AbortController; a newer call or unmount aborts the older one so stale responses never clobber fresh state. Options: timeout, onSuccess, onError.
useCompletion()
function useCompletion(session, options?: UseCompletionOptions): UseCompletionResultStream a single text completion over session.requestStream, accumulating deltas into completion. Returns { completion, isStreaming, error, complete, stop }; stop() cancels, unmount cancels and suppresses late writes.
useChat()
function useChat(session, options?: UseChatOptions): UseChatResultMulti-turn chat over session.requestStream: appends a user message plus a streaming assistant placeholder, accumulates deltas into it, and sends full conversation history to the runtime. Returns { messages, input, setInput, sendMessage, isStreaming, error, stop }; seed history with options.initialMessages.
useInputPresence()
function useInputPresence(session, options?: UseInputPresenceOptions): InputPresenceControlsCaptures keyboard/mouse behind pointer lock (or touch engagement) and publishes it as ephemeral awareness presence on the session — the platform contract for continuous input (default field "input", default 30 Hz). Returns { engage, engageTouch, release, engaged, heldKeys, pressKey, releaseKey, movePointer }. On disconnect the peer's presence state clears automatically.
useSessionDoc()
function useSessionDoc<T>(session, key): { snapshot: T | null; synced: boolean; set(patch): void }
function useSessionDoc<T, U>(session, key, selector: (state: DocState<T>) => U): UReactive view of a named session document, backed by the doc store — the doc (vanilla Yjs) owns state and sync. Without a selector it returns { snapshot, synced, set } and re-renders on every doc change; with a selector it re-renders only when the selected slice changes.
useDocStore()
function useDocStore<T>(session, key): DocStore<T>The underlying Zustand-style binding for a session doc: a read-projection + write-through with selector-granular re-renders. Prefer it over useSessionDoc when you select repeatedly off one doc.
useStreamMessages()
function useStreamMessages(session, name, options?: { cap?: number }): StreamMessageEntry[]A bounded, time-ordered tail of a named stream's data lane. Consuming subscribes this peer to the stream (session.stream(name).messages() opt-in semantics); each entry is { at, payload }, oldest dropped past cap. Cancels cleanly on unmount or name change.
useSessionTrack()
function useSessionTrack(session, name): MediaStreamTrack | nullLatest inbound MediaStreamTrack for a named session stream, or null until the runtime produces it. Thin over session.stream(name).track + .on('track'); needs no provider.
useUrunAudioLevel()
function useUrunAudioLevel(source: MediaStream | MediaStreamTrack | null, options?): UrunAudioLevelSamples an audio source's level through the SDK's shared AudioContext (analysis only — never routes it to the speakers). Options: fftSize (512), intervalMs (100), speakingThreshold (0.02). Returns silence for a null source and during SSR.
Session-state hooks
The building blocks behind Session lifecycle — each pairs with a drop-in component:
function useSessionPhase(session): SessionPhase | null // pairs with UrunSessionStatus / UrunSessionGate
function useSessionWake(session): SessionWake // pairs with UrunSessionWaking
function useSessionEndsAt(session): Date | null // pairs with UrunSessionClock / UrunSessionEnded
function useSessionIdle(session): SessionIdleState | null // pairs with UrunIdleWarninguseSessionPhase— the current phase snapshot, reactively (9 phases; see Types).useSessionWake—{ waking, phase, state?, reason?, since?, seconds }: a live elapsed-seconds view of the pre-live wait (queued/unavailable/provisioning), counted fromphase.wakingSinceas one continuous clock.useSessionEndsAt— the session's declared deadline, ornullwhen the app declared no maximum length.useSessionIdle— the server-raised inactivity warning ({ warning, deadlineEpochS, idleSinceEpochS }) read from the control doc, ornullin the steady state. Confirm presence withsession.touch().useActivation— the live-but-no-media-yet half of the honest lifecycle: follows the core activation watchdog's per-stream progression (activating → still-activating → cold-boot → degraded → first-media) asActivationProgress; pairs withUrunActivationOverlay, which renders it over the video until the element's first decoded frame clears it.
useUrunPrewake()
function useUrunPrewake(options: { app?: string; function: string; intervalS?: number }): PrewakeResult | nullThe scale-to-zero intent signal: while a page that will start a session is mounted, pings the advisory POST /api/sessions/prewake on mount and every intervalS (default 60), so capacity is already warming by the time the user clicks start. Advisory by contract — never throws, never affects a session flow; returns the latest PrewakeResult (or null) for an honest "warming your GPU…" affordance. app defaults to the surrounding UrunProvider's appId.
Component-registry hooks
The built-in components also export headless hooks — useProgressCard, useStatusBadge, useTextStream, useImageFrame, useMetricsPanel — see Component Registry.