Concepts

Status: draft. Terms may be renamed before 0.1.

Terminology

Term Meaning
Bubble One isolated UI instance of an extension, shown inside a host surface.
Host The application that shows Bubbles, brokers calls between them and decides grants.
Surface A host-controlled area where Bubbles appear: a chat thread, a dashboard, a TUI pane.
Extension Something a user installs. Identified by an https URL. The unit of trust. Can provide methods, use other extensions’ methods, and render Bubbles.
Manifest uibubbles.json in the extension’s id directory: identity, modes, provided and used methods, emitted and accepted events, network domains, requested permissions.
Mode How a Bubble renders: Declarative, Worker or Frame. A mode implies no capability.
Call One extension invoking a method another extension provides, always through the host.
Glue A host-owned shared wall between touching Bubbles across which declared events pass.
Foam A cluster of glued Bubbles. Pure data: members plus walls.

Rendering modes

  • Declarative. Data only: an HTML subset the host renders itself. No code from the extension runs. Doubles as the text and TUI fallback.
  • Worker. Third-party code. One hidden sandboxed iframe per third-party extension, one Web Worker per Bubble. The worker’s DOM is mirrored into a Shadow DOM in the host through an allowlist sanitizer with CSS containment.
  • Frame. A visible iframe for full existing web apps. Optional in the spec.

See security for why these differ in strength.

Calls

Extensions call each other through the host, addressed by local alias:

const picked = await uib.ext("contacts").choose({ min: 1, max: 5, fields: ["name", "email"] });
// equivalent: uib.invoke("contacts.choose", { ... })
  • Interactive calls open the callee’s Bubble over the caller, labelled with who is asking. They must begin from a user gesture. The caller receives only what the user picked, and only the fields it requested. Nesting is allowed; the host keeps a stack with a depth limit, blocks cycles and propagates cancel.
  • Headless calls, such as a free/busy query, need a grant in advance which the host checks.

Payloads reuse IETF formats where they exist: JSContact (RFC 9553) and JSCalendar (RFC 8984).

Glue and foam

Touching Bubbles form a shared wall owned by the host. A glue is allowed only where one Bubble’s emits match the other’s accepts, so compatible Bubbles snap together and incompatible ones do not. Only declared events cross.

Lifecycle verbs

Verb Effect
pop A Bubble appears, or (popping it) disappears. Dismissing the instance does not delete the underlying resource.
pin Keep the Bubble available on the surface.
expand Grow from inline to panel to fullscreen.
drag and drop Move one item from a Bubble onto another (a contact onto a meeting). The host runs the drag; the source offers a typed item, and only Bubbles that declare they accept that type become drop targets. The drop is the consent: the receiver gets exactly that item. Keyboard (pick up, move between targets, drop) and touch (long-press) are required, not optional.
glue Attach touching Bubbles across a wall. By the user (drag), an agent (a glued pair pops) or a Bubble (spawn glued).
unglue Split a cluster. Popping one Bubble leaves the others.
spawn A Bubble asks the host to bring another Bubble into being.

Instance lifecycle is distinct from resource lifecycle: popping a Calendar Bubble does not delete the event it showed.

Instance states (draft)

Like blowing a real soap bubble:

State Meaning What the host shows
blowing The instance exists; the extension is loading or the answer is not ready yet. A small bubble right away, breathing, with an optional one-line status (“thinking…”, “checking your calendar…”). It may swell a little as partial results stream in.
inflated The Bubble has reported that it is ready, with its preferred size. The small bubble grows into the final size and shape, with a short spring. Content fades in once it has settled.
popped Dismissed, cancelled or failed. A burst, replaced by a line of text when there was an error.

Two reasons this is more than decoration: the blowing phase covers the real cold-start time of a Worker Bubble (booting its extension’s sandbox and worker), and growing to the reported size is the size handshake between host and Bubble, made visible instead of appearing as a layout jump. With prefers-reduced-motion, the small bubble stays still and the Bubble cross-fades in.