Roamium

Roamium is the Chromium browser engine binary for TermSurf. It wraps libtermsurf_chromium (a C shared library built from the Chromium fork) in a small Rust binary (~400 lines) that handles Unix socket IPC, protobuf message dispatch, and process lifecycle.

How it works

The GUI (Ghostboard) spawns one Roamium process per browser profile. Each process serves exactly one profile — one set of cookies, storage, and cache — a hard constraint of Chromium’s BrowserContext. The GUI passes the IPC socket, the profile’s user-data directory, and the engine’s own listen socket on launch; Roamium enters Chromium’s message loop, creates the profile’s context, registers with the GUI, and then creates tabs and streams GPU layers on demand. For the wire format and topology, see Architecture; for the message types, see the protocol message reference.

Architecture

Roamium follows a two-layer pattern designed to be reusable across browser engines:

  • libtermsurf_chromium — a C shared library that wraps Chromium’s embedding API. Exports the ts_* functions below for lifecycle, profiles, tabs, navigation, input, and state. Built from the Chromium fork.

  • Roamium — a Rust binary that links the C library, connects to the GUI socket, dispatches incoming protobuf messages to ts_* calls, and relays Chromium callbacks back out as protobuf messages.

Source layout

FilePurpose
main.rsEntry point, arg parsing, callback registration, Chromium message loop
dispatch.rsMessage dispatch — routes protobuf messages to FFI calls, relays callbacks
ipc.rsUnix socket connection, length-prefixed protobuf framing, reader loop
ffi.rsFFI bindings to the libtermsurf_chromium C functions
proto.rsGenerated protobuf types (prost)

C API

The ts_* functions exported by libtermsurf_chromium:

Lifecycle

FunctionPurpose
ts_content_mainEnter Chromium’s message loop (blocks)
ts_set_on_initializedRegister the initialization callback
ts_post_taskPost a task to the UI thread
ts_quitShut down Chromium

Profiles (browser contexts)

FunctionPurpose
ts_create_browser_contextCreate a profile (BrowserContext)
ts_create_incognito_browser_contextCreate an ephemeral incognito profile
ts_destroy_browser_contextDestroy a profile

Tabs

FunctionPurpose
ts_create_web_contentsCreate a browser tab
ts_create_devtools_web_contentsCreate a DevTools tab
ts_destroy_web_contentsClose a tab

Navigation and input

FunctionPurpose
ts_load_urlNavigate to a URL
ts_forward_mouse_eventForward a mouse click
ts_forward_mouse_moveForward mouse movement
ts_forward_scroll_eventForward a scroll
ts_forward_key_eventForward keyboard input

State

FunctionPurpose
ts_set_focusSet focus state (browse vs. control)
ts_set_color_schemeSet dark/light mode
ts_set_view_sizeResize the viewport
ts_set_gui_activeSet whether the GUI is active/foreground

Dialog and auth replies

FunctionPurpose
ts_reply_javascript_dialogAnswer a JavaScript dialog (accept/cancel + prompt text)
ts_reply_http_authAnswer an HTTP authentication challenge (credentials)

Callbacks

Chromium fires callbacks on the UI thread (registered with the ts_set_on_* functions). Roamium converts each to a protobuf message and sends it to the GUI:

CallbackProtobuf messagePurpose
on_tab_readyTabReadyTab created, tab_id assigned
on_ca_context_idCaContextGPU layer ready for compositing
on_url_changedUrlChangedPage navigated
on_loading_stateLoadingStateLoading started/finished
on_title_changedTitleChangedPage title updated
on_cursor_changedCursorChangedCursor type changed (pointer, text, …)
on_target_url_changedTargetUrlChangedLink hover target
on_console_messageConsoleMessageConsole log entry from the page
on_renderer_crashedRendererCrashedRenderer process crashed (recovery)
on_http_auth_requestHttpAuthRequestServer requested HTTP authentication
on_javascript_dialog_requestJavaScriptDialogRequestPage opened a JavaScript dialog

The auth and dialog callbacks are request/reply round trips: the *_request callback notifies the GUI and the web TUI, which collects the answer and replies via ts_reply_http_auth / ts_reply_javascript_dialog.

Multi-engine pattern

Roamium is the first engine binary, but the architecture is built for several. Each engine pairs a C shared library wrapping the engine’s embedding API (the ts_* functions) with the reusable ~400-line Rust binary — only the C library changes per engine. Planned engines: Surfari (WebKit), Waterwolf (Gecko), Girlbat (Ladybird) — see the roadmap.

Installation

Homebrew installs Roamium to /opt/homebrew/opt/termsurf-roamium/. That root holds the roamium binary, the Chromium dylibs, .pak resources, ICU data, V8 snapshots, and generated resources under gen/. The GUI resolves the installed engine at /opt/homebrew/opt/termsurf-roamium/roamium. See Getting Started to install.

scripts/build.sh roamium —release
sudo scripts/install.sh roamium