npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

cool-retro-term-renderer

v1.0.1

Published

A WebGL-based CRT terminal renderer for XTerm.js with authentic retro effects

Readme

cool-retro-term-renderer

A WebGL-based CRT terminal renderer for XTerm.js. This library provides authentic retro CRT visual effects for terminal applications, including screen curvature, phosphor glow, scanlines, and more.

npm version

License: GPL-3.0

Preview

Preview

Live demo available at https://remojansen.github.io/

Installation

npm install cool-retro-term-renderer

Peer Dependencies

This library requires three and @xterm/xterm as peer dependencies:

npm install three @xterm/xterm

Quick Start

import { CRTTerminal } from 'cool-retro-term-renderer';
import { Terminal } from '@xterm/xterm';

// Create a container element
const container = document.getElementById('terminal')!;

// Initialize the CRT renderer
const crt = new CRTTerminal({ container });

// Create and configure your XTerm instance
const xterm = new Terminal({
  cols: 80,
  rows: 24,
  cursorBlink: false,
});

// XTerm needs a DOM element to attach to (can be hidden)
const hiddenContainer = document.createElement('div');
hiddenContainer.style.position = 'absolute';
hiddenContainer.style.left = '-9999px';
document.body.appendChild(hiddenContainer);
xterm.open(hiddenContainer);

// Attach XTerm to the CRT renderer
crt.attachXTerm(xterm);

// Now use XTerm as normal - output will render with CRT effects
xterm.write('Hello, CRT World!\r\n');
xterm.write('$ ');

Advanced Usage (Low-Level API)

For more control over the rendering pipeline (e.g., custom Three.js scenes, audio integration, or custom terminal adapters), you can use the lower-level components directly:

import * as THREE from 'three';
import { TerminalFrame, TerminalText } from 'cool-retro-term-renderer';
import { Terminal } from '@xterm/xterm';

const container = document.getElementById('terminal')!;

// Create your own Three.js scene
const scene = new THREE.Scene();
const camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0.1, 10);
camera.position.z = 1;

// Create the renderer
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setClearColor(0x000000);
container.appendChild(renderer.domElement);

// Create the terminal text renderer (handles character rendering and effects)
const terminalText = new TerminalText(window.innerWidth, window.innerHeight);
terminalText.mesh.position.z = 0;
scene.add(terminalText.mesh);

// Create the terminal frame (CRT bezel/border)
const terminalFrame = new TerminalFrame(window.innerWidth, window.innerHeight);
terminalFrame.mesh.position.z = 0.1;
scene.add(terminalFrame.mesh);

// Create XTerm instance (hidden, used as input handler)
const xterm = new Terminal({ cols: 80, rows: 24 });
const hiddenContainer = document.createElement('div');
hiddenContainer.style.position = 'absolute';
hiddenContainer.style.left = '-9999px';
document.body.appendChild(hiddenContainer);
xterm.open(hiddenContainer);

// Sync XTerm dimensions with the calculated terminal grid size
const gridSize = terminalText.getGridSize();
if (gridSize.cols > 0 && gridSize.rows > 0) {
  xterm.resize(gridSize.cols, gridSize.rows);
}

// Listen for grid size changes and resize XTerm
terminalText.onGridSizeChange((cols, rows) => {
  if (cols > 0 && rows > 0) {
    xterm.resize(cols, rows);
  }
});

// Handle window resize
window.addEventListener('resize', () => {
  renderer.setSize(window.innerWidth, window.innerHeight);
  terminalFrame.updateSize(window.innerWidth, window.innerHeight);
  terminalText.updateSize(window.innerWidth, window.innerHeight);
});

// Animation loop
function animate() {
  terminalText.updateTime(performance.now());
  terminalText.renderStaticPass(renderer);
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
}

animate();

Low-Level Components

| Export | Description | |--------|-------------| | TerminalText | Renders terminal characters with CRT effects (shaders, bloom, etc.) | | TerminalFrame | Renders the CRT monitor bezel/frame | | XTermConnector | Syncs an XTerm.js buffer to TerminalText (optional helper) |

TerminalText Methods

| Method | Description | |--------|-------------| | getGridSize() | Get terminal dimensions { cols, rows } | | onGridSizeChange(callback) | Register callback for grid size changes | | updateSize(width, height) | Update renderer dimensions | | updateTime(time) | Update time uniform for animated effects | | renderStaticPass(renderer) | Render effects that don't change per-frame | | setFontColor(color) | Set font color (hex string) | | setBackgroundColor(color) | Set background color (hex string) | | setScreenCurvature(value) | Set screen curvature (0-1) | | setBloom(value) | Set bloom intensity (0-1) | | setBrightness(value) | Set brightness (0-1) | | setFlickering(value) | Set flickering intensity (0-1) | | setStaticNoise(value) | Set static noise (0-1) | | setBurnIn(value) | Set burn-in persistence (0-1) | | setRasterizationMode(mode) | Set scanline mode (0-3) | | dispose() | Clean up resources |

API Reference

CRTTerminal

The main class that creates the WebGL renderer and manages the CRT effect pipeline.

Constructor

new CRTTerminal(options: CRTTerminalSettings)

CRTTerminalSettings

| Property | Type | Default | Description | |----------|------|---------|-------------| | container | HTMLElement | required | The container element to render into | | fontColor | string | "#0ccc68" | Font color in hex format (green) | | backgroundColor | string | "#000000" | Background color in hex format | | screenCurvature | number | 0.3 | Screen curvature amount (0-1) | | rgbShift | number | 0 | RGB shift/chromatic aberration (0-0.01) | | bloom | number | 0.5538 | Bloom intensity (0-1) | | brightness | number | 0.5 | Brightness level (0-1) | | ambientLight | number | 0.2 | Ambient light glow (0-1) | | chromaColor | number | 0 | Chroma color (0=mono, 1=full color) | | flickering | number | 0.1 | Flickering intensity (0-1) | | horizontalSync | number | 0.08 | Horizontal sync distortion (0-1) | | jitter | number | 0.1997 | Jitter/displacement (0-1) | | staticNoise | number | 0.1198 | Static noise intensity (0-1) | | glowingLine | number | 0.2 | Scanning beam intensity (0-1) | | burnIn | number | 0.2517 | Phosphor burn-in persistence (0-1) | | rasterizationMode | number | 1 | 0=none, 1=scanline, 2=pixel, 3=subpixel | | rasterizationIntensity | number | 0.5 | Scanline intensity (0-1) |

Methods

| Method | Description | |--------|-------------| | attachXTerm(xterm: Terminal) | Attach an XTerm.js terminal instance | | detachXTerm() | Detach the currently attached XTerm instance | | getGridSize() | Get the terminal grid size { cols, rows } | | focus() | Focus the attached XTerm terminal | | dispose() | Clean up all resources |

Advanced Access

For advanced usage, you can access the underlying components:

crt.getTerminalText()  // TerminalText renderer
crt.getRenderer()      // THREE.WebGLRenderer
crt.getScene()         // THREE.Scene
crt.getCamera()        // THREE.OrthographicCamera

Visual Effects

The library implements a two-pass rendering pipeline that replicates the visual characteristics of CRT monitors:

Static Pass (Pass 1)

  • Screen curvature distortion
  • RGB shift (chromatic aberration)
  • Bloom (phosphor glow)
  • Brightness adjustment

Dynamic Pass (Pass 2)

  • Horizontal sync distortion
  • Jitter (random displacement)
  • Burn-in (phosphor persistence)
  • Static noise
  • Glowing line (scanning beam)
  • Rasterization (scanlines)
  • Flickering
  • Ambient light

Examples

Custom Green Theme (Default)

const crt = new CRTTerminal({
  container,
  fontColor: '#0ccc68',
  bloom: 0.6,
  screenCurvature: 0.3,
});

Amber Terminal

const crt = new CRTTerminal({
  container,
  fontColor: '#ffb000',
  bloom: 0.5,
  burnIn: 0.3,
});

High-Fidelity CRT

const crt = new CRTTerminal({
  container,
  screenCurvature: 0.4,
  flickering: 0.15,
  horizontalSync: 0.1,
  staticNoise: 0.15,
  burnIn: 0.3,
  rasterizationMode: 1,
  rasterizationIntensity: 0.6,
});

Minimal Effects

const crt = new CRTTerminal({
  container,
  screenCurvature: 0,
  flickering: 0,
  horizontalSync: 0,
  jitter: 0,
  staticNoise: 0,
  burnIn: 0,
  rasterizationMode: 0,
});

Browser Support

Requires WebGL support. Works in all modern browsers:

  • Chrome 56+
  • Firefox 51+
  • Safari 15+
  • Edge 79+

Development

# Install dependencies
npm install

# Generate assets (fonts and textures)
npm run generate-assets

# Build the library
npm run build

# Build in watch mode
npm run dev

# Lint and format
npm run lint-and-format

License

GPL-3.0

Credits

This project is a port to WebGL from cool-retro-term by Filippo Scognamiglio.

This library uses the Terminus Font by Dimitar Zhekov, licensed under the SIL Open Font License (OFL).