thcThought Control

rrweb

Record and replay the web as JSON snapshot and mutation events.

rrweb.com ↗repo ↗docs ↗Event format ↗Full snapshot (glossary) ↗Incremental snapshot (glossary) ↗Sentry fork getsentry/rrweb ↗Sentry replay overhead benchmark ↗PostHog session replay over MCP ↗

license
MIT; community project funded through Open Collective sponsors. Major vendors maintain forks (getsentry/rrweb; PostHog ships @posthog/rrweb-* packages).
language
TypeScript
backing
Community maintainers (e.g. Juice10, eoghanmurray) with Open Collective sponsorship; commercial session-replay vendors contribute and fork.
stars
20,253 (as of 2026-10-09)
downloads
3,171,818/week npm rrweb + 751,449/week @rrweb/record (2026-10-01..07); posthog-js (15.8M/week) bundles PostHog's rrweb fork
latest release
rrweb@2.1.7, 2026-10-02
first release
2018-11
borrow

The de facto UI-history format; scene should mirror its event structure for screen history and export, while its message log supplies the 'why' rrweb lacks.

Borrow from it: take a specific idea, API or format.

the steelman: the best honest case for it

rrweb is the proof that a UI's entire history can be a compact, strictly-typed JSON stream: one full snapshot with node ids, then tiny id-addressed patches for every mutation, input, scroll and mouse move, with periodic checkpoints so you can seek anywhere and drop old segments. That simple format won — ~3.2M weekly downloads, the base of PostHog's and Sentry's session replay — because it is cheap to capture in production, privacy-aware by default (inputs masked, elements blockable), extensible via plugins, and replayable live or later. A fan would say scene's 'screen_at' and export format are already designed here: keyframe + deltas, meta events, custom events, checkpoints every N, and a replayer with seek, speed and skip-inactive.

scores
datadriveseeedittimeratetermpxteachmatureopen
UI as data4 scene 5A recorded UI is fully serializable JSON (snapshot + id-addressed mutations) you can store, diff, send — but only as capture, not as an authoring format.
Agent can drive it1 scene 5Nothing to drive; agents read files or vendor MCP summaries.
Agent can see it3 scene 5Structured events readable; DOM-at-time requires scripting the replayer.
Small, targeted edits1 scene 5Event stream is id-addressed patches, but nothing edits a live UI.
Time travel3 scene 0Human/programmatic seek in a replayer; no agent tool, no fork.
Live data rate3 scene 5Records mutations as they happen and supports liveMode; no published rate numbers.
Terminal native0 scene 5
Pixel graphics1 scene 4Replays DOM/canvas in a browser iframe; no rendering of its own.
Teaching2 scene 3Replays are used to show what happened; no narration or takeover.
Maturity5 scene 1
Openness5 scene 4

rrweb scene now scene planned

how agents use it

How

No agent interface in rrweb itself; it is a JS library. Agents reach rrweb data through vendors: PostHog's MCP can search recordings, read a recording's metadata (duration, interaction and console counts, person summary), manage playlists and summarize sessions with PostHog AI; Replay Vision has AI watch recordings. An agent can also parse the event JSON directly or script the Replayer.

Wiring it in

Low to read raw events (JSON); moderate to build seek/inspect tools on top of the Replayer or rrdom in Node.

Seeing the result

Events are structured JSON (node-id tree + mutations), so the DOM at any time can be reconstructed programmatically; vendor MCPs give summaries rather than DOM at time t.

Small edits

Not applicable: recordings are captured, not authored. Custom events can be added to a stream.

History

Replayer seek (play(t)/pause(t)), speed, skip-inactive, live mode; no fork. Vendor MCPs (PostHog) expose search/summary, not seek.

In short

An excellent, widely adopted UI-history format with no agent surface of its own; agents mostly see it through vendors' summaries.

architecture

The recorder serializes the DOM into a node tree with ids (FullSnapshot), then emits strictly-typed JSON IncrementalSnapshot events for every change: DOM mutations (via MutationObserver), mouse moves/interactions, scroll, viewport resize, input, media, stylesheet rules, canvas mutations, fonts. A recording begins with a Meta event (URL, viewport) and a FullSnapshot; each page load starts a new Meta+FullSnapshot pair, and streams can be concatenated. The Replayer rebuilds the DOM in a sandboxed iframe and applies events on a timer; it can seek (play(t), pause(t)), change speed, skip inactivity, and run in liveMode fed by addEvent. checkoutEveryNth / checkoutEveryNms insert periodic full snapshots so old segments can be dropped and seeks start nearby.

performance

rrweb itself publishes no benchmarks; the best numbers come from vendors measuring their forks (Sentry: ~+400 ms TBT on a mutation-heavy page). Cost scales with DOM mutation volume.

adoption and upkeep

Adoption

The open-source substrate of web session replay; the leading open replay products run on it or forks of it.

Used by: PostHog (posthog-js depends on @posthog/rrweb, @posthog/rrweb-record), Sentry (maintains getsentry/rrweb fork for Session Replay)

Maintainability

Steady, community-maintained; vendors carrying forks is both a safety net and a fragmentation risk.

Releases: Frequent patch releases in 2026: 2.1.2–2.1.4 (2026-09-08), 2.1.5 (2026-09-17), 2.1.6 (2026-09-18), 2.1.7 (2026-10-02). The legacy `rrweb` package is deprecated in favour of @rrweb/record and @rrweb/replay. · Contributors: 143 (GitHub contributors API, incl. anonymous) · Recent: ~33 commits in the last 90 days (top: Juice10 9, eoghanmurray 8, github-actions 7). · Bus factor: medium: two core maintainers plus vendor forks that would keep it alive

weaknesses
and thc-scene

Overlap

A serialized UI tree with stable ids plus a stream of id-addressed changes over time; seek by snapshot + deltas; live streaming mode. scene's frames and patches by node id are the same idea.

What scene would be reinventing

The recording format for screens over time (keyframe + incremental events, meta header, custom events, periodic checkouts) and the replayer controls (seek, speed, skip idle). scene's planned screen_at/export should reuse this structure.

The gap it leaves

rrweb records but never authors or controls: no live agent control, no app state/messages, no fork, no terminal output. scene records its own messages and state, so it can fork and replay deterministically, not just show pixels-equivalent.

What to borrow

  • Event envelope {type, data, timestamp} with Meta (terminal size, theme, capabilities) + FullSnapshot + Incremental (patch, key, mouse, resize, data-source update) + Custom (agent narration, marks).
  • checkoutEveryNth / checkoutEveryNms: periodic full snapshots for seek and retention windows.
  • Skip-inactive and speed controls for replays and tours.
  • Masking options at capture time (e.g. mark nodes or data sources as private, never exported).
  • liveMode: the same replayer consumes a live stream, which gives scene 'watch an agent/learner live' for free.
  • A plugin hook on record and replay.
sources
  1. rrweb-io/rrweb (GitHub API: stars, license, releases, contributors) github.com
  2. rrweb guide.md (record/replay options) github.com
  3. rrweb Events docs rrweb.com
  4. Sentry Web Replay Performance Overhead docs.sentry.io
  5. getsentry/rrweb fork github.com
  6. posthog-js package metadata (rrweb fork dependencies) registry.npmjs.org
  7. Use Session Replay over PostHog MCP posthog.com
  8. Replay.io: Runtime Replay versus Session Replay docs.replay.io
  9. npm downloads API (rrweb) api.npmjs.org