Skip to content

feat: add @wterm/serialize for session persistence#36

Open
mvanhorn wants to merge 1 commit into
vercel-labs:mainfrom
mvanhorn:feat/35-wterm-serialize
Open

feat: add @wterm/serialize for session persistence#36
mvanhorn wants to merge 1 commit into
vercel-labs:mainfrom
mvanhorn:feat/35-wterm-serialize

Conversation

@mvanhorn
Copy link
Copy Markdown

@mvanhorn mvanhorn commented Apr 19, 2026

Closes #35.

Adds a new package @wterm/serialize that snapshots wterm state (grid cells, scrollback, cursor, modes, palette) into a portable string and restores it into a fresh terminal. Matches the capability xterm.js users get from @xterm/addon-serialize.

Usage

import { WTerm } from "@wterm/dom";
import { serialize, restore } from "@wterm/serialize";

const term = new WTerm();
term.open(document.getElementById("terminal")!);
term.write("some output\r\n");

const snapshot = serialize(term);
localStorage.setItem("wterm-session", snapshot);

const next = new WTerm();
next.open(document.getElementById("terminal")!);
restore(next, localStorage.getItem("wterm-session")!);

Approach

  • Snapshot is an ANSI stream: replaying it via term.write() reproduces the exact cell state, which reuses the renderer you already have rather than introducing a parallel restore path
  • Encodes visible grid + scrollback + cursor position + SGR attributes + DECSET modes + 256/truecolor palette
  • Zero runtime deps
  • New package only; no edits to @wterm/core or @wterm/dom

Testing

17 new tests in packages/@wterm/serialize/src/__tests__/:

  • encode: SGR attrs, 256-color, truecolor, scrollback, DECSET modes, cursor position
  • roundtrip: serialize then restore produces an identical grid snapshot

Full repo CI is green: pnpm test 151 passing, pnpm format:check, pnpm typecheck, pnpm build all clean.

Demo

serialize demo

Left terminal holds a live session. serialize() returns a snapshot string. A fresh WTerm mounts after reload and restore() rebuilds the exact state into the right terminal.

Notes

  • Docs page and API reference entry added per AGENTS.md
  • No new runtime dependencies
  • Ready for review

🤖 Generated with Claude Code

Adds a new package that serializes wterm terminal state (grid, scrollback,
cursor, modes) into a portable snapshot and restores it into a fresh terminal,
matching the capability xterm.js users get from @xterm/addon-serialize.

Closes vercel-labs#35.
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 19, 2026

@mvanhorn is attempting to deploy a commit to the Vercel Labs Team on Vercel.

A member of the Team first needs to authorize it.

Comment on lines +51 to +53
const parts = [snapshot.payload];

if (snapshot.modes.altScreen) parts.push("\x1b[?1049h");
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const parts = [snapshot.payload];
if (snapshot.modes.altScreen) parts.push("\x1b[?1049h");
const parts: string[] = [];
if (snapshot.modes.altScreen) parts.push("\x1b[?1049h");
parts.push(snapshot.payload);

When restoring an alt screen snapshot, the payload content is written to the main screen first, then \x1b[?1049h switches to a clean empty alt screen, causing all serialized alt screen content to be lost/hidden.

Fix on Vercel

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Headless mode + serialize like Xterm.js offers

1 participant