ghostty-web is an MIT-licensed TypeScript library that brings Ghostty's WASM-compiled VT100 terminal emulator to the browser behind an xterm.js-compatible API, built for web developers who want a correct terminal in the page without abandoning their existing xterm.js integration.
What it is
ghostty-web is a browser terminal library published to npm as ghostty-web. It ships as a WASM-compiled parser taken from Ghostty — the same code that runs the native Ghostty application — rather than a reimplementation, and it carries zero runtime dependencies in a bundle of roughly 400KB of WASM. The project is written in TypeScript under the MIT licence, is filed in this registry under Productivity & Utilities / Browsers & Extensions, and carries the topics browser, ghostty, library, and terminal. It was originally created for Mux, Coder's desktop app for isolated, parallel agentic development, but the README states it is designed to be used anywhere.
The concrete problem it solves is the hand-written terminal emulation inside xterm.js, the renderer behind VS Code, Hyper, and countless web terminals. xterm.js reimplements terminal emulation in JavaScript, so every escape sequence, edge case, and Unicode quirk is coded by hand and inevitably develops gaps. ghostty-web replaces that JavaScript emulator with Ghostty's battle-tested parser while keeping the calling convention the same, so a project migrates by changing one import: @xterm/xterm becomes ghostty-web. It therefore sits in the browser terminal ecosystem as a drop-in substitute for the rendering and parsing layer, not as a full terminal application.
Key capabilities
- API compatibility with xterm.js through
init, Terminal, term.open(), term.onData(), and term.write().
- WASM-compiled parser built from Ghostty's source, sharing the emulator that runs the native app.
- Proper grapheme handling for complex scripts such as Devanagari and Arabic, where xterm.js has rendering issues.
- Full support for the
XTPUSHSGR/XTPOPSGR escape sequences, which xterm.js does not support.
- Zero runtime dependencies with a roughly 400KB WASM bundle.
- One-line migration path: change the import from
@xterm/xterm to ghostty-web.
- A runnable demo,
npx @ghostty-web/demo@next, that starts a loopback-only HTTP server with a real shell on http://127.0.0.1:8080, protects /ws with a per-run same-origin token, and rejects cross-origin WebSocket handshakes.
Who uses it and how
- Mux, Coder's desktop application for isolated, parallel agentic development, is the original consumer of the library.
- Web terminal projects already built on xterm.js swap the import and keep their existing
Terminal configuration and data plumbing.
- Developers evaluating the library run
npx @ghostty-web/demo@next locally, which works best on Linux and macOS, to get a real shell in the browser.
- Deployments that serve the demo through extra hostnames or a wildcard bind such as
HOST=0.0.0.0 must set GHOSTTY_ALLOWED_HOSTS=host1,host2; HOST= binds elsewhere.
- A live demo runs on an ephemeral VM at
ghostty.ondis.co, hosted by Greg from disco.cloud.
Getting started
Install with npm install ghostty-web, then await init() before constructing a Terminal. For a working client and server example, run npx @ghostty-web/demo@next or read the demo source.
How it compares
Within the tools named in the facts, ghostty-web positions itself directly against xterm.js: it keeps the API but swaps the emulation core for Ghostty's, gaining complex-script rendering and XTPUSHSGR/XTPOPSGR support. It is also distinct from Ghostty itself, since Ghostty is the native application whose parser this library compiles to WASM. No paid products are listed as being replaced.
When to use it — and when not to
Anyone who runs the demo must understand that it starts a real local shell, and the README advises avoiding remote exposure unless that risk is understood. Building from source requires Zig and Bun and applies patches/ghostty-wasm-api.patch to Ghostty's tree via bun run build, so contributors take on a patch-maintenance burden, albeit one the authors expect to shrink as libghostty matures and a native Ghostty WASM distribution becomes consumable. Teams wanting a frozen emulator with no upstream tracking should not pick it.
project readme (upstream, from github) — read inline
ghostty-web

Ghostty for the web with xterm.js API compatibility — giving you a proper VT100 implementation in the browser.
- Migrate from xterm by changing your import:
@xterm/xterm → ghostty-web
- WASM-compiled parser from Ghostty—the same code that runs the native app
- Zero runtime dependencies, ~400KB WASM bundle
Originally created for Mux (a desktop app for isolated, parallel agentic development), but designed to be used anywhere.
Try It
Live Demo on an ephemeral VM (thank you to Greg from disco.cloud for hosting).
On your computer:
npx @ghostty-web/demo@next
This starts a loopback-only HTTP server with a real shell on http://127.0.0.1:8080. The demo protects /ws with a per-run same-origin token and rejects cross-origin WebSocket handshakes. Works best on Linux and macOS.
To intentionally bind somewhere else, set HOST=. If you serve the demo through extra hostnames or a wildcard bind such as HOST=0.0.0.0, also set GHOSTTY_ALLOWED_HOSTS=host1,host2. Avoid remote exposure unless you understand the risk: the demo starts a real local shell.

Comparison with xterm.js
xterm.js is everywhere—VS Code, Hyper, countless web terminals. But it has fundamental issues:
xterm.js reimplements terminal emulation in JavaScript. Every escape sequence, every edge case, every Unicode quirk—all hand-coded. Ghostty's emulator is the same battle-tested code that runs the native Ghostty app.
Installation
npm install ghostty-web
Usage
ghostty-web aims to be API-compatible with the xterm.js API.
import { init, Terminal } from 'ghostty-web';
await init();
const term = new Terminal({
fontSize: 14,
theme: {
background: '#1a1b26',
foreground: '#a9b1d6',
},
});
term.open(document.getElementById('terminal'));
term.onData((data) => websocket.send(data));
websocket.onmessage = (e) => term.write(e.data);
For a comprehensive client server example, refer to the demo.
Development
ghostty-web builds from Ghostty's source with a patch to expose additional
functionality.
Requires Zig and Bun.
bun run build
Mitchell Hashimoto (author of Ghostty) has been working on libghostty which makes this all possible. The patches are very minimal thanks to the work the Ghostty team has done, and we expect them to get smaller.
This library will eventually consume a native Ghostty WASM distribution once available, and will continue to provide an xterm.js compatible API.
At Coder we're big fans of Ghostty, so kudos to that team for all the amazing work.
License
MIT