Browser

A composable React viewport for agent-browser. Stream a real session, visualize agent actions and hand control to a person without changing transports.

pnpm add @browser-ui/react

Demo

Built by danielsims

Find Mac mini, configure the desktop and a Studio Display, then hand the live session back at Apple’s final review.

Usage

Pass the stream URL from your agent-browser session and the small amount of state your application already owns.

agent-session.tsx
import { AgentBrowser } from "@browser-ui/react";

type SessionBrowserProps = {
  streamUrl: string;
  operating: boolean;
  action?: string;
  onTakeControl: () => void;
  onEndSession: () => Promise<void> | void;
};

export function SessionBrowser({
  streamUrl,
  operating,
  action,
  onTakeControl,
  onEndSession,
}: SessionBrowserProps) {
  return (
    <AgentBrowser
      streamUrl={streamUrl}
      viewportSize={{ width: 1440, height: 900 }}
      operating={operating}
      operatingLabel={action}
      operatingShader={{
        variant: "tide",
        direction: "top-left-to-bottom-right",
        speed: "fast",
      }}
      showPictureInPicture
      showFullscreen
      onTakeControl={onTakeControl}
      onEndSession={onEndSession}
    />
  );
}

Props

The composed API stays controlled where product behavior matters and provides sensible defaults for presentation.

Stream

streamUrlstring · required

WebSocket endpoint returned by agent-browser. Frames and user input travel over this connection.

viewportSize{ width, height }

Remote browser resolution, independent from the rendered component. Keep it fixed to preserve desktop breakpoints in PiP.

displayAspectRatioCSS aspect-ratio

Shape of the rendered component only. It never changes the remote viewport.

colorScheme"light" | "dark" | "system"

Controls Browser UI chrome independently from the streamed page. System follows the host device preference.

onUrlChange(url) => void

Reports navigation messages emitted by the remote browser.

onViewportResize(width, height) => void

Reports the requested remote viewport dimensions to the session owner.

onStatusChange(status) => void

Reports connecting, connected, disconnected and error states.

Agent activity

operatingboolean · false

Shows the activity shader and pauses direct viewport input while the agent owns the session.

operatingLabelstring

Current action displayed in the compact status control.

operatingShader{ variant, direction, speed }

Selects the active-agent shader and configures its movement across the viewport.

agentCursorBrowserAgentCursorState

Normalized cursor position and pressed or typing state for visualizing live or recorded agent actions.

agentCursor.sizenumber · 24

Controls the rendered cursor width in CSS pixels.

agentCursor.backgroundColorCSS color · #2f6bff

Controls the soft radial glow beneath the cursor.

onActivityChange(activity) => void

Reports structured agent activity, including labels and live cursor state.

loadingLabelstring

Copy shown while the WebSocket is connecting or reconnecting.

Display

variant"framed" | "bare"

Use the standalone glass frame or an unstyled edge-to-edge surface.

showControlsboolean · false

Adds the optional address and reload controls.

showPictureInPictureboolean · false

Adds the floating picture-in-picture control.

showFullscreenboolean · false

Adds application fullscreen without changing the remote viewport size.

fullscreenTargetHTMLElement | null

Constrains fullscreen to a host element and tracks its bounds and border radius.

mode"inline" | "picture-in-picture" | "fullscreen"

Controls the display mode from your application.

defaultModedisplay mode · "inline"

Initial display mode when Browser manages its own state.

onModeChange(mode) => void

Reports transitions between inline, PiP and fullscreen.

displayControlsReactNode

Adds host-owned actions to Browser UI's display-control strip.

displayControlsClassNamestring

Class name applied to the package-owned display-control strip.

Session control

accessBrowserSessionAccess

Projects the viewer's capabilities and active control lease into the browser surface.

interactiveboolean · false

Enables local input intent; projected access still decides whether commands are authorized.

onTakeControl() => void

Called when the person stops the workflow and takes ownership of browser input.

onEndSession() => Promise<void> | void

Renders the terminal action and delegates destruction of the underlying browser to the host.

endSessionLabelstring · End session

Overrides the accessible label for the package-owned terminal action.

Navigation

urlstring

Current URL shown by the optional controls.

onNavigate(url) => void

Receives address submissions so the session owner can navigate agent-browser.

onReload() => void

Receives reload requests from the optional browser controls.

ariaLabelstring

Accessible name for the interactive remote viewport.

viewportClassNamestring

Class name applied directly to AgentBrowserViewport.