- Native OSC 8 hyperlinks: the built-in and Ghostty cores preserve hyperlink metadata through rendering, scrollback, reflow and resets. The DOM renderer exposes safe absolute HTTP(S) links as native anchors, with Command-click activation on macOS and Control-click on Windows/Linux while plain clicks remain terminal-owned (#116)
- Complete Ghostty grapheme strings: combining marks and ZWJ sequences now cross the WASM boundary as complete clusters in both the viewport and scrollback instead of being truncated to a base codepoint (#111)
- Ghostty theme color responses: OSC 10 and OSC 11 queries now return the configured foreground and background colors with the original BEL or ST terminator (#113)
- Atomic Ghostty synchronized output: Ghostty exposes DEC mode
?2026state and block generations so the DOM scheduler holds intermediate frames and paints the completed burst once (#114) - Bounded scrollback DOM: history rows are virtualized with viewport overscan, preserving native selection and the visible history position across rollover and resize while keeping mounted rows bounded (#115, #61)
- Direct animation-frame scheduling: normal writes request an animation frame without an intermediate timer while retaining one pending render per frame and synchronized-output cancellation semantics (#112)
- @Railly
- Pixel-aligned block gradients — vertical fractional block glyphs now snap their gradient stops to whole pixels, preventing horizontal rules from jogging between cells at fractional row-height boundaries (#104, #81)
- Ordered terminal query responses — the built-in core queues every response instead of overwriting a single pending value, and the DOM adapter drains them in order even when writes arrive in chunks or an
onDatacallback throws (#105) - Atomic synchronized output — DEC mode
?2026now holds intermediate paints and exposes one completed frame, with a fixed one-second recovery ceiling for unterminated blocks and generation-aware deadlines for consecutive blocks (#106, #57) - Browser mouse and focus reporting — the DOM adapter now emits SGR press, drag, release and wheel events for modes
1000,1002and1006, reports focus for mode1004, and preserves native Shift selection (#107, #55) - Viewport history across vertical resize — shrinking pushes only the rows above the cursor into scrollback, growing refills from the newest history, and wrapped rings are indexed from their write position. Growing now consumes restored scrollback rows, so
getLineoffsets can shift across a resize and hosts retaining an offset must re-read it (#108, #43, #89) - Terminal responses in
@wterm/ghostty— DA1, DSR operating status, CPR and DECRQM queries now produce ordered responses through a bounded FIFO instead of being silently dropped (#109)
- @ivebenfreed
- @Ramalama2
- @Railly
- Wide characters occupied one cell — CJK, fullwidth forms and emoji painted two columns while the grid gave them one, so every occurrence pushed the rest of the row right and cursor-addressed redraws landed a column early.
CellDatagainswidth, the core advances by it, and the DOM renderer skips continuation cells (#102, #54, #71, #101) - Blank scrollback in
@wterm/ghostty—get_scrollback_linewas an unimplemented stub returning 0, so every scrolled-back row rendered empty even though the row count was correct (#98) - Style leaking across screens —
get_viewportreadRenderState.Cell.stylewithout checkingstyle_id, resurfacing the style of whatever occupied the cell in an earlier render pass, including one against the alternate screen (#96) GhosttyCore.load()under bundlers that inline modules — Bun's dev server resolvesimport.meta.urlto a path on the build machine, so afile:URL reached the browser andfetchreported onlyFailed to fetch. The loader now names the cause and points atwasmPath, and reports a non-OK response or a non-WASM body instead of failing insideWebAssembly.instantiate(#99)scrollbackLimitdocumented as lines — ghostty reads it as a byte budget, so an 80-column terminal retains about 1150 rows at the 10000 default, not 10000 (#98)- Cell width guessed by Unicode block — hand-written ranges called 1209 assigned characters wide that Unicode calls narrow, including enclosed alphanumerics, domino tiles and several arrow blocks. The table is generated from East Asian Width data now (#102)
- Wide pairs split at a narrower width — a row dropped into scrollback during a resize kept a wide cell whose continuation was left behind, and a scrollback row read into a narrower grid spilled a column past its end (#102)
@wterm/ghostty/ghostty-vt.wasmsubpath export — the binary is now addressable through the package, so apps on bundlers that cannot resolve the default can serve it themselves (#99)- Container WASM build —
rebuild-wasm:dockerruns the existing build script in Linux, for hosts where Zig 0.15.x cannot link a native build runner. Output is byte-identical to a host build (#98)
- @ctate
- @njbrake
- @Railly
- WASM view invalidation — cached
DataViewandUint8Arrayviews over WASM memory became detached when the module grew memory mid-call, throwing ongetCell,getScrollbackCelland multi-chunkwriteRaw(#92) - Scrollback colors in
@wterm/ghostty—getScrollbackCell()packedfgRgb/bgRgbregardless ofcolorFlags, so cells with no explicit color rendered black instead of the terminal default (#93) escapeHTMLdouble quotes — the DOM renderer's escape helper left"unescaped (#94)
- Test coverage for
@wterm/ghostty— the package had no test setup, soturbo run testskipped it entirely. It now runs in CI like the other packages (#93)
- @hobostay
- @Railly
- Ghostty core — new
@wterm/ghosttypackage withGhosttyCoreimplementingTerminalCorevia libghostty compiled to WASM, providing an alternative terminal rendering engine (#62) TerminalCoreinterface — extracted into a standalone module in@wterm/coreso custom cores (like Ghostty) can be swapped in cleanly (#62)- Ghostty example — minimal vanilla TypeScript example using
@wterm/ghosttyand@wterm/dom(#62) - Ghostty docs page — install, quick start, how it works, and switching cores guide (#62)
- Write coalescing — output writes are now batched with
setTimeoutin the DOM renderer to reduce animation flashing (#62) - innerHTML renderer — switched to
innerHTMLfor fewer DOM operations per frame (#62) - Deferred PTY spawn — PTY is now spawned on first
RESIZEevent to eliminate the strayzsh %artifact (#62) - Local example routes — split into
/(built-in core) and/ghosttywith a core toggle (#62)
- @ctate
- Fixed npm publish —
workspace:*peer dependencies are now resolved to real version ranges in published tarballs (#58) - Fixed Vue package missing from releases —
@wterm/vueis now included in the release workflow (#58)
- @ctate
- Vue support — added
@wterm/vuepackage with<Terminal />component,useTerminalcomposable, auto-echo whenonDatais omitted, anddebugprop (#30, #46)
- Trusted publisher releases — CI now uses trusted publisher workflow for npm publishing (#45)
- @ctate
- @posva
- Fixed background rendering not applying correctly (#34)
- Fixed bracketed paste security — ESC bytes are now stripped from pasted content to prevent escape sequence injection (#33)
- Fixed Zig version in build configuration (#28)
- @aaronjmars
- @ctate
- E2E browser tests — added Playwright test suite with 11 tests covering rendering, keyboard input, focus, cursor movement, scrollback, and resize (#25)
- Vite example — minimal vanilla TypeScript terminal with
@wterm/domand@wterm/just-bash, no framework needed (#24) - Markdown Streaming example — Next.js app using
@wterm/react,@wterm/markdown, and AI SDK to stream LLM output into a terminal (#24) - API Reference page — single consolidated reference for all terminal options, React props, WTerm methods, imperative handle, WebSocketTransport, and WasmBridge (#25)
- Just Bash docs — install, quick start, options, virtual FS, network access, and keyboard shortcuts (#23)
- Markdown docs — streaming examples (vanilla + React), supported syntax, and LLM output guide (#23)
- Core / Advanced docs — WasmBridge API, types, headless example, and WebSocketTransport with remote shell example (#23)
- Zig 0.16.0 — migrated build system and rebuilt
wterm.wasmwith Zig 0.16.0 - Vitest workspace — 165 unit tests across all five packages with V8 coverage and Turbo integration (#21)
- Zig CI — added Zig test step and WASM drift check to CI workflow (#22)
- WTerm integration tests — 33 tests for the DOM orchestrator (#22)
- Fixed just-bash README — corrected broken usage example (#22)
- @ctate
- Zero-boilerplate usage —
<Terminal />andnew WTerm(el)now work out of the box with noonDatawiring required. WhenonDatais omitted, typed input is echoed back automatically (#16) - Simpler getting-started examples — docs, READMEs, and configuration pages updated to show the minimal one-liner usage first, with
onData/useTerminaldocumented as an advanced pattern (#16, #17) - Faster docs layout — removed server-side cookie reads from the root layout, making it synchronous; chat panel state is now fully client-driven via
useSyncExternalStore
- @ctate
- Fixed terminal height — replaced
maxHeightwith deterministicheightcomputed fromrows * rowHeight, preventing layout drift caused bygetBoundingClientRect()timing - Fixed border rendering — switched docs terminal borders from CSS
bordertoinset box-shadowto avoid border-width interference with height calculations
- Row height variable — added
--term-row-heightCSS custom property so row and block heights are defined in one place
- @ctate
- Fixed Shift key producing input in the terminal when pressed alone
- Fixed focus scroll — focusing the terminal no longer causes unwanted page scroll
- Fixed height lock —
maxHeightcalculation now accounts forborder-boxsizing and border widths
- Docs tables — option/property tables on the Vanilla and React pages now use proper HTML
<table>elements - Docs routing — the introduction page is now served at
/with a redirect from/introduction - Star count cache — reduced GitHub star count revalidation interval from 24 hours to 1 hour
- @ctate
- Fixed caret focus state — the cursor now correctly shows/hides based on terminal focus
- Fixed paste handling — clipboard paste works reliably in the terminal
- Fixed Ctrl+A and Ctrl+E — jump-to-start and jump-to-end key bindings now work correctly
- Fixed left/right arrow keys in the just-bash package for proper cursor movement
- Fixed Cmd+A — select-all support in the terminal
- Fixed clear line — Ctrl+U now properly clears the current input line
- Line buffering — input is now buffered per-line for more accurate editing and replay
- Fixed broken links in docs and package READMEs
- @ctate
- Embedded WASM binary — the ~12 KB WASM binary is now base64-inlined into the JS bundle, eliminating the need to copy and serve
wterm.wasmas a static asset.wasmUrlis now optional and only needed when serving the binary separately for caching or CDN use. - Updated docs and READMEs to reflect the zero-setup WASM approach
- Fixed renderer formatting — minor code style cleanup in the DOM renderer
- @ctate
- Fixed block element rendering — Unicode block characters (U+2580–U+259F) now render correctly using CSS gradients and quadrant compositing instead of font glyphs
- Improved PTY error handling — shell spawn failures are now caught gracefully with a user-facing error message before closing the connection
- Removed rounded corners in the local example for a cleaner full-screen look
- Fixed scroll not working correctly
- Fixed click focus triggering when text is selected
- Styled greeting message with dim text formatting
- Refactored greeting message internals
- Included
wterm.wasmas a static asset in package configuration - Added release process workflow
Initial release.