Skip to content

Terminal Context

The Terminal context renders elements to a character-based terminal using Unicode braille patterns (U+2800–U+28FF). Each terminal cell encodes a 2×4 grid of sub-pixel dots, giving 8× the resolution of plain text. It supports ANSI truecolor for full-color output.

Demo

The demo below renders a bar chart live in an xterm.js terminal widget — the same @ripl/terminal code that runs in Node.js:

Installation

The terminal context is provided by the @ripl/terminal package. For Node.js usage, also install @ripl/node:

bash
npm install @ripl/terminal @ripl/node

Usage

Node.js

Import from @ripl/node to automatically configure the runtime factory:

ts
import '@ripl/node';

import {
    createCircle,
    createNodeOutput,
    createRect,
    createTerminalContext,
} from '@ripl/node';

const output = createNodeOutput();
const context = createTerminalContext(output);

createCircle({
    fill: '#3a86ff',
    cx: context.width / 2,
    cy: context.height / 2,
    radius: 40,
}).render(context);

Browser (xterm.js)

Since @ripl/terminal is runtime-agnostic, you can wire it to any output that implements the TerminalOutput interface — including an xterm.js instance in the browser:

ts
import { Terminal } from '@xterm/xterm';
import {
    BrailleRasterizer,
    TerminalContext,
} from '@ripl/terminal';

const xterm = new Terminal({ disableStdin: true });
xterm.open(document.getElementById('terminal'));

const output = {
    write: (data) => xterm.write(data),
    columns: xterm.cols,
    rows: xterm.rows,
};

const context = new TerminalContext(output, {
    rasterizer: new BrailleRasterizer(xterm.cols, xterm.rows),
});

How It Works

The terminal context:

  1. Records drawing commands (lines, arcs, curves, rects) from elements
  2. Rasterizes them onto a sub-pixel grid using algorithms like Bresenham's line, midpoint circle, and adaptive Bézier subdivision
  3. Applies scanline fill for filled shapes
  4. Maps CSS colors to ANSI truecolor escape sequences
  5. Encodes each 2×4 cell into a Unicode braille character
  6. Flushes the serialized output to the TerminalOutput adapter

Extensible Rasterizer

The default BrailleRasterizer can be swapped for alternative character sets by implementing the Rasterizer interface:

ts
interface Rasterizer {
    readonly pixelWidth: number;
    readonly pixelHeight: number;
    resize(cols: number, rows: number): void;
    setPixel(x: number, y: number, color: string): void;
    setChar(col: number, row: number, char: string, color: string): void;
    clear(): void;
    serialize(): string;
}

Pass a custom rasterizer via the rasterizer option when creating a context.

Limitations

  • No interaction — Terminal contexts do not support pointer events or hit testing
  • No gradients — CSS gradient strings are not supported; use solid colors
  • No image drawingdrawImage is a no-op
  • Monospace text — Text is placed at character-grid positions; font metrics are approximate
  • No transformsrotate, scale, translate are currently no-ops
  • Resolution — Limited by braille dot density (2×4 per cell)

When to Use Terminal

Terminal is the best choice when:

  • Server-side rendering — Visualize data in CI/CD pipelines, monitoring dashboards, or CLI tools
  • No browser available — Render charts and graphics in headless environments
  • Quick prototyping — See rendering output without setting up a browser environment