docs / architecture
Architecture
One process, two loopback servers
Rume is a single Node process bound to loopback. Nothing is exposed to your network.
127.0.0.1:8787 # editor panel (the UI you click around in) 127.0.0.1:8788 # dev proxy → your project's dev server
The dev proxy
The proxy forwards 8788 → your dev server, strips only X-Frame-Options and the frame-ancestors CSP so the app can render inside the panel, and injects the Rume runtime <script> into the page's <head>. Every request is token-gated.
The runtime
The injected runtime talks to the panel over postMessage. It handles hover/click selection (resolving each element back to a data-rume-loc — its file, line, and column), reads computed style, and reports a heartbeat and persistent selection outline.
Writers
Rume ships named writers for each source shape it edits directly:
- Inline-style — JSX
style={ }edits (via Babel) - Text — text content changes
- Plain CSS — stylesheet rule patches
- Tailwind — utility class edits
- Static HTML — raw
styleattribute edits by line:col
Under the hood
- Selection — a React fiber walk first; a DOM-ancestor fallback reads
data-rume-locfor non-React pages (static HTML). - Verification — the panel polls computed style before it lets you submit, riding out HMR lag. Publish only fires on a clean verify.
- Streaming — App Router pages are streamed (not buffered) so hydration and RSC are untouched; only the small head region is buffered for injection.