Skip to content

Contributing

Daniel Imms edited this page Aug 22, 2023 · 18 revisions

Xterm.js is maintained by several core team members, but we would love to receive contributions from everyone!

To contribute either code, documentation or issues to xterm.js please read the Contributing document beforehand. All you need to contribute is an editor that supports JavaScript/TypeScript, a browser. You will need Node.js installed locally to get all the features working in the demo.

Running the Demo

The xterm.js repo contains a barebones demo implementation, designed for the development and evaluation of the library only. Note that exposing the demo to the public as is would introduce security risks for the host.

Below you can find instructions on how to run the demo on different platforms. We recommend using Yarn to make sure the dependencies are installed correctly but npm should work most of the time. You will also need variable dependencies for the node-pty dependency like python and make, see detailed instructions here.

Linux or macOS

First, be sure that a C++ compiler such as GCC-C++ or Clang is installed, then run the following commands in your terminal:

yarn
yarn setup
yarn start      # Run this in its own terminal
yarn run watch  # Run this in its own terminal

Then open http://127.0.0.1:3000 in a web browser to access the demo.

Windows

First, ensure node-gyp is installed and configured correctly, then run the following commands in your terminal:

yarn
yarn setup
yarn start      # Run this in its own terminal
yarn run watch  # Run this in its own terminal

Then open http://127.0.0.1:3000 in a web browser to access the demo.

Note: Do not use ConEmu, as it seems to break the demo for some reason.

Development Container

If you have Docker and VS Code installed you can open an xterm.js development container without needing to install node and the other build dependencies, just install the Remote Containers extension, open the folder and then reopen the folder via the notification. Once the window is initialized run the following in the integrated terminal:

yarn
yarn setup
yarn watch  # Run this in its own terminal
yarn start  # Run this in its own terminal

SourceLair

SourceLair will run the demo and builder in parallel automatically. Just make sure to choose the "Node.js" project type, when cloning the xterm.js repo (or just use this shortcut; https://lair.io/xtermjs/xtermjs).

Then open your project's Public URL to access the demo.

Foreman (or other Procfile runner)

First, be sure that a C++ compiler such as GCC-C++ or Clang is installed, then run the following commands in your terminal:

yarn
foreman start  # Replace foreman with "honcho", "forego" etc. depending on your runner

Then open http://0.0.0.0:3000 in a web browser to access the demo.

Testing

Tests are run using the following npm scripts:

  • yarn test-unit [pattern1 [pattern2...]]: This runs the unit tests. Pass in specific patterns to run only a subset of tests.
  • yarn test-api [--headless]: This runs the API integration test, you must have the server server (yarn start) running to run these. Add --headless to run in headless mode.

Architecture

Layering

The project uses a layered architecture similar to VS Code's where the project is split into 3 modules:

  • common: The lowest level module, it can run in either a browser or a node.js environment and does not depend on anything.
  • browser: Can run only in a browser environment and depends on common, the public directory contains the API for xterm
  • headless: Depends on common, the public directory contains the API for xterm-headless

Any public directory contains code that implements the public API, for example browser/public/Terminal.ts implements an API façade by wrapping internal objects from browser and common the wraps the objects in browser. It is not recommended for any xterm.js embedder to touch the internal objects (private API) as what they do and whether they even exist is not guaranteed and could change, even across patch versions.

Dependency injection

Dependency injection in xterm.js is implemented using a simplified version of that used in VS Code. To use it decorations are used, here is an example of injecting IBufferService into a constructor:

class Example {
  constructor(
    @IBufferService bufferService: IBufferService
  ) {
  }
}

In order for DI to work this class must be created using the IInstantiationService:

const example = instantiationService.createInstance(Example);

To implement a new service it must contain a serviceBrand property and then be registered to the IInstantiationService:

interface IExampleService {
  serviceBrand: undefined;
}
class ExampleServiceImpl implements IExampleService {
  public serviceBrand: undefined;
}

const exampleServiceImpl = new ExampleServiceImpl();
this._instantiationService.setService(IExampleService, exampleServiceImpl);

Addons

Addons built by the xterm.js team are located in this repository under the addons/ folder. They are in their own separate folders and are treated as individual npm modules, but during development they leverage the dependencies in the root-level package.json file.

Enabling debug mode

Xterm.js has a debug mode that allows you to view what's being evaluated by the terminal. To enable this mode, run the demo and execute the following in the console:

term.setOption('logLevel', 'debug');

Any data sent to the terminal should be output in the console.

Third party dependencies

We prefer to not include any non-dev third party dependencies in order to keep our code minimal, performant and secure. If you plan on adding a dependency on a third party library it's a good idea to discuss the need in an issue with the maintainers first.