The @wterm/dom package provides a framework-free terminal that works with plain HTML/CSS/JS.
npm install @wterm/dom<div id="terminal"></div>
<script type="module">
import { WTerm } from "@wterm/dom";
import "@wterm/dom/css";
const term = new WTerm(document.getElementById("terminal"), {
onTitle(title) {
document.title = title;
},
});
await term.init();
</script>By default, typed input is echoed back to the terminal. Pass onData when you need control over input — for example, sending it to a server:
const term = new WTerm(document.getElementById("terminal"), {
onData(data) {
socket.send(data);
},
});
await term.init();The WTerm constructor accepts all shared terminal options (cols, rows, core, wasmUrl, autoResize, cursorBlink, onData, onTitle, onResize). Pass a TerminalCore instance to the core option to use an alternative emulation backend.
See WTerm Methods for the full list of instance methods (init, write, resize, focus, destroy).
When a terminal application enables SGR mouse tracking or focus reporting, WTerm sends those reports through onData with keyboard input and host responses.
Import the stylesheet and apply a theme class to the terminal element:
import "@wterm/dom/css";Built-in themes: theme-solarized-dark, theme-monokai, theme-light:
element.classList.add("theme-monokai");All colors use CSS custom properties (--term-fg, --term-bg, --term-color-0 through --term-color-15) so you can define your own theme with plain CSS.
Connect to a PTY backend over WebSocket:
import { WTerm, WebSocketTransport } from "@wterm/dom";
const term = new WTerm(el, { cols: 80, rows: 24 });
await term.init();
const ws = new WebSocketTransport({
url: "ws://localhost:8080/pty",
onData: (data) => term.write(data),
});
ws.connect();
term.onData = (data) => ws.send(data);See the full WebSocketTransport reference for all options, methods, and properties.