Simple web Xterm and ANSI terminal emulator - pure JavaScript, no dependencies
- Introduction
- Setup
- Usage
- Sample server
- Full documentation
- Live example
- Screenshots
- Caveats
- TODO
- Enjoy
The goal of this project is to provide a simple, pure javascript terminal emulator frontend (i.e., the client side). Connecting to a terminal service is a user's responsibility. For testing purposes, a very basic terminal server is available here.
This project is still under development.
The source is a single JavaScript file (src/xwterm.js); once downloaded (e.g., by cloning the repository), it is ready to use. To produce a minified version, run make from the project's root directory. terser is required to do this. The minified file is dist/xwterm.min.js. You can also download the minified file directly from the GitHub releases page. It is recommended to use release versions, unless your goal is to contribute to this project, as the latest commit may contain experimental or incomplete code.
The following HTML code shows a minimal example of use. It generates a page containing only a terminal with default properties:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
</body>
<script type="module">
import { AnsiTerm } from "./xwterm.js";
var ansi = new AnsiTerm();
</script>
</html>
The only thing the programmer has to do is to create an instance of the AnsiTerm
class.
You can find a more detailed explanation here: Basic example.
By default, AnsiTerm's constructor connects its main "div" container to the document body, but you can put a terminal inside a container of your choice by specifying its ID:
...
<div id="myterminal"></div>
...
var ansi = new AnsiTerm("myterminal");
The constructor also accepts some configuration parameters, which you can pass as an array of key/value pairs. The most important keys are:
nLines
: number of text lines (default 25)nColumns
: number of characters in a line (default 80)containerId
: the ID of the container where you want the terminal to be placed (default "", which means that the constructor will use the document's body)channelType
: the type of channel by which the terminal gets the stream of characters to display and sends events. "http" (alias "rest", default), "websocket", "dummy" or "custom" are recognized (see below for details).
Example:
var ansi = new AnsiTerm( { nLines: 40, nColumns: 120, containerId: "myterminal" } );
The terminal can use these kinds of channels to communicate with the server (NOTE: Here we use the term "server" in an extensive sense, to indicate any form of data source and destination that is suitable to be managed by a terminal.)
- HTTP
- WebSocket
- Dummy
- Custom protocol
A detailed description of channels is here: Communication drivers
For testing purposes, you can find a minimal terminal server written in Python3 in the
example
folder.
Do not use the example as if it were a real terminal server; it is meant only to familiarize yourself with the AnsiTerm class and ease its development.
The server implements both HTTP and WebSocket services on TCP port 8000 and 8001 respectively. By default, the server accepts local connections only
A detailed description of the server is here: Sample server
A (still incomplete) documentation of the package, mainly classes and their methods, is here: API Documentation
You can test a working example of xwterm here: Simple JavaScript Console, where an instance of AnsiTerm hosts a basic JavaScript console.
Here are some images taken while running the shell and some applications that require
full support of graphics functions (Midnight Commander, htop, vim):
Please remember that this project is in its early stage. The project was born out of a specific need of mine in a controlled environment; to make it fully usable, a certain effort of generalization is still required.
As the project grows, some details in the public interface (e.g., parameter names) may change. This may happen at least until the first "non-beta" release (v1.0.0) is published.
Development and test have been done mainly on recent versions of Chrome and Firefox. Safari has been tested very superficially. No other browsers have been tested at this time.
About Safari, there is at least a known problem: iOS soft keyboard doesn't appear if the page doesn't contain an input field. AnsiTerm's canvas is not considered an input field by Safari, that's why I had to add a simple hand-made soft keyboard. This problem sometimes appears on Android devices too.
Internationalization, and encoding in general, is also an issue I neglected. My daily environment is Western Europe (Italy), where "latin1" or "Windows-1252" are sufficient. More sophisticated encodings are expected to be problematic.
Many things to do:
- Clean up code and add comments.
- Add better support for server-side sessions (e.g., cookies, access tokens...)
- Add support for hyperlinks and hyperlink sequences (e.g,
\e]8;;http://example.com\e\\This is a link\e]8;;\e
) - Add custom CSS properties to configure the terminal. Currently, the configuration comes from a set of parameters passed to the constructor.
- Add a configuration item to choose the terminal mode (e.g., "pure ANSI", "xterm", "xterm-256"...).
- Improve the soft keyboard. The current implementation reflects my particular need: Italian keyboards don't have "Tilde" nor "Backquote" keys...
- Add management of alternate character set (see "G0/G1" character set selection sequences).
- Add a history buffer (and a scroll bar, of course).
- Implement resizing and responsiveness. This means the terminal should maintain logical lines as generated by the server (i.e., the sequences of characters ending with a line feed), because when the number of columns changes, it is expected that logical lines are preserved instead of being truncated to the previous visual line length.