docs
TypeScript SDKCore Concepts

React Providers

UrunProvider, useApp, and the auth bridges that connect your React app to a deployed uRun App

UrunProvider configures the application 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 application 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 application 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.

PropTypeRequiredDescription
baseUrlstringif jwt/orgId setBase URL of your uRun backend (e.g. https://urun.sh)
orgIdstringif jwt setYour organization ID
appIdstringyesThe deployed App useApp() resolves
authProviderstring—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 application 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:

BridgeImportUse for
UrunWorkOSProvider@urun-sh/react/workosPure React WorkOS applications
UrunWorkOSProvider@urun-sh/react/next-workosNext.js WorkOS applications
UrunAuthProvider@urun-sh/reactAny provider — supply a getAccessToken callback
UrunJwtProvider@urun-sh/reactA 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 application 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:

Was this page helpful?

0/2000

On this page