mrkeyoor.com_
Thu 03 Sept 14:38 UTC
Webevaluationupdated 03 Sept 2026

xterm.js review

xterm.js is a TypeScript terminal emulator that renders an interactive command-line interface inside a web page or Electron app. It handles terminal display and input, while your application supplies the shell or remote process, transport, authentication, and session lifecycle.

trackingstars / 7d
Verdict

Our xterm.js checkout installed 541 packages in 19 seconds and built in 15 seconds, but its 10-second test step failed because no compiled test files were found. It remains the sensible default for teams that need a mature browser terminal component and will supply the secure process layer around it. Hold the rollout if multilingual input, old browsers, or an unmodified v5 integration is a hard requirement, because each has a current, specific risk.

We ran it

Lab card: what happened when we ran xterm.jsScreenshot of xterm.js (xtermjs.org)
Install✓ · 19s541 packages · 343 MB
Build✓ · 15s
Tests✗ · 10sran, no count parsed
Known vulns00 critical · 0 high · 0 moderate · 0 low (npm audit)
Repo761 files~94,580 lines of source · 18.6 MB · 4 CI workflows · tests dir

Answers from our run

Does xterm.js build from source?

Dependencies installed in 19 seconds (541 packages), and the build succeeded in 15 seconds. We cloned commit c58ea36 into a clean Debian container with 3 CPUs and no project-specific setup.

Do xterm.js's tests pass?

The test command failed in our container, and its output did not report a pass or fail count.

Does xterm.js have known vulnerabilities in its dependencies?

npm audit found none in the dependency tree at the time of our run.

Who should not use xterm.js?

Anyone looking for a downloadable terminal or a JavaScript shell: the README says xterm.js is only the frontend and points to a separate pseudoterminal such as node-pty.

What are the alternatives to xterm.js?

ttyd, Tabby, Windows Terminal. Our xterm.

Setup3/5Build passed in 15 seconds, but the default test command failed
Docs4/5Clear boundary, browser matrix, API types, add-ons, and examples
Community5/521,131 stars, a September push, and fast current issue work
Maturity4/5Used in major products, though v6 and input bugs need testing

Who it’s for

Developers building browser IDEs, cloud consoles, container shells, or device administration panels.
Electron teams that need a terminal component rather than a complete terminal application.
Products that can pair the browser renderer with a pseudoterminal and an authenticated transport.
Teams prepared to test keyboard layouts, accessibility, resizing, and renderer add-ons in their supported browsers.

Who it’s NOT for

Anyone looking for a downloadable terminal or a JavaScript shell: the README says xterm.js is only the frontend and points to a separate pseudoterminal such as node-pty.
Products that must support old or fixed browser versions: official support covers only the latest Chrome, Edge, Firefox, and Safari.
Input-heavy products that cannot tolerate current IME edge cases: issue 6144 reports a dropped first Chinese punctuation character, and issue 5887 reports a lost second character with some macOS IMEs.
Teams expecting a drop-in move from v5: the v6.0.0 notes list breaking changes to scrolling, key mapping, options, and renderer choices.
Contributors who require the default test command to pass after a clean install and build: our run found no compiled test files and exited with code 1.

Setup reality

Our sandbox installed 541 npm packages in 19 seconds and used 343 MB. The build succeeded in 15 seconds, but tests failed with exit code 1 after 10 seconds because the runner found no files matching **/out-esbuild/**/*.test.js. Npm audit reported 0 known vulnerabilities.

Embedding the published package needs its CSS, a container element, and code wiring terminal input and output. A real remote shell also needs a pseudoterminal, process cleanup, an authenticated transport, resize handling, and authorization; xterm.js supplies none of those server duties.

Official browser support is limited to current Chrome, Edge, Firefox, and Safari. Add-ons are separate packages, experimental APIs can change, and v6.0.0 includes breaking option and renderer changes, so pin and test the core with every add-on.

The 94,580-line project renders terminals but runs no shell

xterm.js parses terminal control sequences, maintains a screen buffer, captures keyboard and mouse input, and renders the result in a browser element. Our checkout contained about 94,580 source lines across 761 files, reflecting much more than a styled text area. Curses programs, selection, scrollback, Unicode, links, custom glyphs, theming, and alternate screen behavior all meet inside this component. The dividing line is firm: xterm.js does not start Bash, open SSH connections, or decide who may access a machine.

A usable remote terminal therefore has two halves. The browser sends onData events to an authenticated backend, and that backend writes them to a pseudoterminal such as node-pty. Process output travels back to term.write, while resize events must update both the renderer and PTY. In our development checkout, npm installed 541 packages and occupied 343 MB. The consumer package has a different footprint. Contributors and CI machines still carry the repository's development cost.

Thirteen maintained add-ons keep the core focused

The README lists 13 maintained add-ons covering WebSocket attachment, clipboard access, fitting, images, ligatures, progress, search, serialization, Unicode variants, web fonts, web links, and WebGL rendering. Keeping these capabilities separate lets an application avoid shipping every optional path. It also creates a compatibility matrix: core, renderer, browser, font, and add-on versions need to be exercised together. Experimental APIs carry weaker stability promises and may change more sharply than the ordinary semantic-versioned surface.

Version 6.0.0 made that maintenance cost visible. Its release notes move the overview-ruler option, change viewport and scrollbar behavior, remove the old Alt-to-Ctrl arrow mapping, and drop the canvas renderer in favor of DOM or WebGL. The same release adds ESM output, shadow-DOM support for WebGL, detailed ligatures, synchronized output, and a progress add-on. Our build succeeded in 15 seconds, but a clean compiler result cannot tell whether a product's custom keybindings or layout assumptions survived those changes.

What happened when we ran it

Our run cloned commit c58ea36 into a fresh unprivileged container with 3 CPUs, 8 GB of RAM, and Node 22. The repository occupied 18.6 MB before dependencies. npm completed installation in 19 seconds, adding 541 packages and taking 343 MB on disk. The build then succeeded in 15 seconds. Npm audit reported 0 known vulnerabilities across the installed dependency tree: 0 critical, 0 high, 0 moderate, and 0 low.

The test command failed with exit code 1 after 10 seconds. It invoked npm run test-unit, which ran node ./bin/test_unit.js, then printed Error: No test files found: "**/out-esbuild/**/*.test.js". The log contains no test-case summary because the runner did not discover files at that path. We will not guess why the expected compiled tests were absent. The narrow finding is that install and build passed, while the repository's default test route did not run unit cases in our sandbox.

Version 6.0.0 still needs product-specific input tests

Terminal input crosses browser event order, operating-system composition, keyboard layout, and shell editing rules. Issue 6144 reports that xterm.js 6.0.0 can drop the first full-width punctuation character from the macOS Chinese input source in a WKWebView. Issue 5887 describes rapid pairs losing the second character with some third-party macOS IMEs across v5.5.0, v6.0.0, and a v6.1.0 beta. The reports cover specific configurations and do not establish behavior for every IME.

Wide characters create another boundary. Issue 6135 says Alt-click cursor positioning emits movement by buffer cell, while common line editors move by character. In the report's abc中文def example, double-width characters cause the target to overshoot. A product serving CJK users should automate composition and cursor-placement tests with its actual browser shell. Our repository scan found a tests directory and 4 CI workflows, yet the failed local discovery step means we cannot claim those scenarios passed on commit c58ea36.

WebGL speed brings lifecycle and version constraints

The optional WebGL add-on moves rendering into a GPU-backed canvas, a useful choice for dense output. Issue 6068 reports that disposing repeated WebGL terminals can leave contexts alive until Chromium starts losing contexts used by an active terminal. Issue 6143 describes addon-webgl 0.19.0 throwing during disposal with xterm.js 5.5.0 even though the declared peer range accepts that core version. Both reports concern cleanup paths that simple typing demos rarely exercise.

Applications with tabs, split panes, reconnection, or session restoration should repeatedly create and dispose terminals during testing. Track context-loss events, listener cleanup, PTY termination, and WebSocket closure. The repository had 236 combined issues and pull requests on September 3, 2026, so an open report is not unusual for this project size. What matters is whether the exact core and add-on versions in your lockfile reproduce the behavior, followed by a pinned fix or a renderer fallback.

September 2026 activity outweighs the older stable tag

GitHub recorded the last push on September 2, 2026, while stable v6.0.0 was published on December 22, 2025. The README explains that stable releases happen when needed and beta packages are published continuously from master. VS Code commonly tracks a recent beta, but the page advises stability-sensitive users to use betas mainly for testing unless they can follow incoming changes. This model gives active consumers fixes sooner at the price of closer release monitoring.

Recent issue handling supports the active-project reading. A publishing outage filed on August 24, 2026 was closed within an hour, while performance and image-rendering reports also moved that month. Our 10-second failed test launch is still a release gate for anyone changing the repository itself. For an application consumer, xterm.js remains the strongest general browser-terminal base here, provided the backend security, browser matrix, input methods, resize behavior, and add-on disposal paths are treated as product code rather than library defaults.

Alternatives

ProjectWhat it isPick it when
ttydA command-line program that shares a terminal over the web and uses xterm.js for display.pick this instead when you want a ready web-terminal server rather than a frontend component.
TabbyA complete desktop terminal and SSH client built with web technologies.pick this instead when users need an installable terminal application rather than an embeddable library.
Windows Terminal gh↗Microsoft's native terminal application for Windows command-line tools and shells.pick this instead when the job is a Windows desktop terminal and browser embedding is irrelevant.

What people are saying

  1. [velocity-scout] xtermjs/xterm.js

Sources

  1. xterm.js repository and README
  2. xterm.js 6.0.0 release
  3. macOS Chinese IME punctuation report
  4. macOS IME dropped-character report
  5. CJK Alt-click cursor report
  6. WebGL context disposal report
  7. WebGL add-on peer-range report

More web reviews

stylex · brave-browser · desktop · alpine · drawio · carbon · the whole board →