React Providers
UrunProvider, useApp, and the auth bridges that connect your React app to a deployed uRun app
UrunProvider configures the app proxy; useApp() hands you the deployed app; auth bridges supply the browser's access tokens. That is the whole entry point — there is no separate session/compositor provider tree to assemble.
The provider stack
A typical app nests an auth bridge around UrunProvider:
import '@urun-sh/react/styles.css'
import { UrunProvider, useApp } from '@urun-sh/react'
import { UrunWorkOSProvider } from '@urun-sh/react/workos' // Next.js: '@urun-sh/react/next-workos'
export default function App() {
return (
<UrunWorkOSProvider clientId="client_...">
<UrunProvider baseUrl="https://urun.sh" orgId="your-org-id" authProvider="workos" appId="my-app">
<Player />
</UrunProvider>
</UrunWorkOSProvider>
)
}UrunProvider
UrunProvider configures the app proxy that useApp() returns. In the explicit-JWT setup shown above, the browser sends orgId plus a user/session JWT (resolved by the auth bridge); uRun validates it server-side.
| Prop | Type | Required | Description |
|---|---|---|---|
baseUrl | string | if jwt/orgId set | Base URL of your uRun backend (e.g. https://urun.sh) |
orgId | string | if jwt set | Your organization ID |
appId | string | yes | The deployed app useApp() resolves |
authProvider | string | — | Auth provider id, e.g. "workos" |
UrunProvider also supports a self-mint mode that omits baseUrl/orgId/jwt entirely and fetches a token server-side instead — see the full prop reference on the Providers page.
useApp()
useApp() returns the deployed app proxy. Each property access is a deployed Python function; calling it returns a render-safe Session.
function Player() {
const app = useApp()
const session = app.generate({ prompt: 'a sunset' }) // render-safe
const video = session.stream('video')
useEffect(() => {
if (video.track && ref.current) ref.current.srcObject = new MediaStream([video.track])
}, [video.track])
return <video ref={ref} autoPlay muted />
}useApp() is render-safe: repeated app.generate(args) calls with the same args during re-renders reuse the same session. session.stream(name) and session.doc(name) are likewise stable. See the App reference for the full Session surface (.stream, .doc, .onPhase, .disconnect).
Auth bridges
UrunProvider needs a source of short-lived access tokens. Pick the bridge that matches your auth:
| Bridge | Import | Use for |
|---|---|---|
UrunWorkOSProvider | @urun-sh/react/workos | Pure React WorkOS apps |
UrunWorkOSProvider | @urun-sh/react/next-workos | Next.js WorkOS apps |
UrunAuthProvider | @urun-sh/react | Any provider — supply a getAccessToken callback |
UrunJwtProvider | @urun-sh/react | A static JWT (tests / customer-JWT) |
// Generic provider with your own token source:
import { UrunAuthProvider } from '@urun-sh/react'
<UrunAuthProvider getAccessToken={async () => myTokenStore.current()}>
<UrunProvider baseUrl="https://urun.sh" orgId="your-org-id" authProvider="workos" appId="my-app">
{children}
</UrunProvider>
</UrunAuthProvider>No secrets in the browser
The bridges forward short-lived user JWTs only. Never pass a server API key or the urun_… deploy key to a browser client.
Errors
Wrap your app in UrunErrorBoundary to catch session/transport errors and render a fallback instead of crashing the tree.
Media components
Below the provider, media I/O is declarative: send with <Camera> / <Mic>, show with <Video> / <Image> / <Audio>, loop voice with <Voice> — one session per <Session>, or an explicit session prop per component. Copy-paste recipes: Inputs & outputs.
Related:
- Getting Started — the full first-app walkthrough
- App reference —
App,Session, streams, docs - Transport — session phases, reconnection, viewer attach