A terminal emulator for the web.
wterm ("dub-term") renders terminal rows as DOM text, so native text selection, copy and paste, browser find, and screen readers work on the mounted rows. The core is a VT parser written in Zig and compiled to a ~49 KB WASM binary.
npm install @wterm/dom @wterm/reactFor Vue or Svelte, install @wterm/vue or @wterm/svelte with @wterm/dom instead of the React package. Vanilla JavaScript needs only @wterm/dom. The WASM binary is embedded in the package, so no extra file needs to be served.
import { Terminal } from "@wterm/react";
import "@wterm/react/css";
function App() {
return <Terminal />;
}In vanilla JavaScript, mount a terminal on an element:
import { WTerm } from "@wterm/dom";
import "@wterm/dom/css";
const term = new WTerm(document.getElementById("terminal"));
await term.init();To connect a shell, send keyboard input from onData to a PTY backend and write its output back with term.write(), or use WebSocketTransport from @wterm/core. The SSH and local shell examples show both ends. Every framework is covered in Get started.
A terminal core parses escape sequences and holds the screen and scrollback. The DOM renderer reads the core's dirty rows on each animation frame and updates only those rows. History is a ring buffer, and only a bounded window of it is mounted in the DOM.
There are two cores. The built-in Zig core loads by default. @wterm/ghostty swaps in libghostty for fuller VT compatibility, including Kitty images, OSC 133 shell integration, and reflow of soft-wrapped lines. Both implement the TerminalCore interface, so the renderer and framework components work with either (Pluggable cores).
For pages with many busy terminals, renderer: "webgl" paints from one shared WebGL2 context while DOM text keeps selection, find, and screen readers working, and WorkerCore moves parsing off the main thread (WebGL renderer, Worker core).
| Package | Description |
|---|---|
@wterm/core |
Headless WASM bridge, TerminalCore interface, WebSocket transport |
@wterm/dom |
DOM renderer and input handler for vanilla JavaScript |
@wterm/react |
React component and useTerminal hook |
@wterm/vue |
Vue 3 component and template ref API |
@wterm/svelte |
Svelte component and callback API |
@wterm/ghostty |
VT emulation core powered by libghostty |
@wterm/just-bash |
In-browser Bash shell powered by just-bash |
@wterm/markdown |
Render Markdown in the terminal |
Set webmcp on a terminal to register WebMCP tools. In-page agents can then list terminals, read the screen and scrollback, wait for output, type commands, and press keys:
<Terminal webmcp={{ name: "shell" }} onData={send} />Add readOnly: true to the webmcp options when agents should read a terminal without typing into it or pressing keys.
term.readText() returns a text snapshot of retained history and the active screen. The docs are also available as Markdown from wterm.dev/llms.txt.
| Topic | Docs |
|---|---|
| Install and first terminal | Get started |
| Options, renderers, cores, WebSocket transport | Configuration |
| Built-in themes and CSS custom properties | Themes |
| Methods, events, selection, search, images | API reference |
| Framework bindings | React, Vue, Svelte, Vanilla JS |
| Ghostty core, image limits, shell integration | Ghostty |
| In-browser shell and Markdown output | just-bash, Markdown |
| Agent tools | WebMCP |
| Runnable apps | examples/ |
| Release notes | Changelog |
This repo is a pnpm workspace with Turborepo. Use Zig 0.16.0 or later, Node.js 24 or later, and pnpm 11. Dev servers run behind portless, installed globally.
pnpm install
zig build test
pnpm build
pnpm testzig build -Doptimize=ReleaseSmall writes zig-out/bin/wterm.wasm and web/wterm.wasm. The committed binary is packages/@wterm/core/wasm/wterm.wasm, and CI fails when it does not match the Zig sources, so copy the release build there, run pnpm --filter @wterm/core build to regenerate the embedded copy, and commit the binary with any change under src/.
CONTRIBUTING.md covers the Ghostty WASM build, the docs site, the examples, and the PTY, replay, and performance suites. AGENTS.md lists the files to update with each change and the release process.
Apache-2.0