Node.js Platform
Using unblessed in Node.js applications.
Installation
npm install @unblessed/node
# or
pnpm add @unblessed/node
# or
yarn add @unblessed/node
Quick Start
import { Screen, Box } from "@unblessed/node";
// Create screen
const screen = new Screen({
smartCSR: true,
title: "My TUI App",
});
// Create widget
const box = new Box({
parent: screen,
top: "center",
left: "center",
width: "50%",
height: "50%",
content: "Hello from Node.js!",
border: { type: "line" },
style: { border: { fg: "cyan" } },
});
// Global key handler
screen.key(["q", "C-c"], () => process.exit(0));
// Render
screen.render();
Runtime Auto-Initialization
@unblessed/node automatically initializes the Node.js runtime when imported:
// Happens automatically on import
import { Screen } from "@unblessed/node";
// Runtime is ready - no manual setup needed!
const screen = new Screen();
How it works: The package runs auto-init.ts which calls setRuntime(new NodeRuntime()) before any widgets are created.
Node.js-Specific Features
Direct TTY Access
Full access to Node.js TTY capabilities:
import { Screen } from "@unblessed/node";
const screen = new Screen({
input: process.stdin, // Custom input stream
output: process.stdout, // Custom output stream
terminal: "xterm-256color", // Terminal type
});
// Access underlying TTY
const tty = screen.program.term;
console.log("Terminal:", tty);
Process Integration
Integrates with Node.js process:
// Exit handlers
process.on("exit", () => {
screen.destroy();
console.log("Cleanup complete");
});
// Signal handlers
process.on("SIGINT", () => {
screen.destroy();
process.exit(0);
});
process.on("SIGTERM", () => {
screen.destroy();
process.exit(0);
});
// Uncaught errors
process.on("uncaughtException", (error) => {
screen.destroy();
console.error("Error:", error);
process.exit(1);
});
File System Access
Read files for content or configuration:
import { Box } from "@unblessed/node";
import { readFileSync } from "fs";
const content = readFileSync("./data.txt", "utf8");
const box = new Box({
parent: screen,
content: content,
scrollable: true,
});
Environment Variables
Access environment configuration:
const isDev = process.env.NODE_ENV === "development";
const debugMode = process.env.DEBUG === "true";
const screen = new Screen({
debug: debugMode,
log: isDev ? "./debug.log" : undefined,
});
Screen Options
Full Option List
interface ScreenOptions {
// Program options
input?: NodeJS.ReadStream; // Input stream (default: process.stdin)
output?: NodeJS.WriteStream; // Output stream (default: process.stdout)
terminal?: string; // Terminal type (default: auto-detect)
// Display options
smartCSR?: boolean; // Smart cursor save/restore (default: false)
fastCSR?: boolean; // Fast CSR (default: false)
resizeTimeout?: number; // Resize debounce (default: 300ms)
useBCE?: boolean; // Use background color erase (default: false)
fullUnicode?: boolean; // Full Unicode support (default: false)
dockBorders?: boolean; // Dock borders (default: false)
// Behavior options
cursor?: {
artificial?: boolean; // Artificial cursor (default: false)
shape?: "block" | "underline" | "line";
blink?: boolean;
color?: string;
};
title?: string; // Window title
forceUnicode?: boolean; // Force Unicode (default: false)
dump?: boolean; // Dump output to file (default: false)
log?: string; // Log file path
debug?: boolean; // Debug mode (default: false)
warnings?: boolean; // Show warnings (default: false)
autoPadding?: boolean; // Auto padding (default: false)
tabc?: string; // Tab char (default: spaces)
}
Common Configurations
High Performance:
const screen = new Screen({
smartCSR: true,
fastCSR: true,
useBCE: true,
resizeTimeout: 100,
});
Unicode Support:
const screen = new Screen({
fullUnicode: true,
forceUnicode: true,
});
Development/Debug:
const screen = new Screen({
debug: true,
log: "./debug.log",
warnings: true,
dump: true,
});
Terminal Compatibility
Supported Terminals
macOS:
- iTerm2 ✅
- Alacritty ✅
- Kitty ✅
- Terminal.app ✅
Linux:
- gnome-terminal ✅
- konsole ✅
- xterm ✅
- terminator ✅
Windows:
- Windows Terminal ✅
- ConEmu (partial)
- cmd.exe (limited)
Terminal Detection
Automatic terminal detection:
import { Screen } from "@unblessed/node";
const screen = new Screen({
smartCSR: true, // Auto-detected based on terminal
});
// Check detected terminal
console.log("Terminal:", screen.program.terminal);
console.log("Supports 256 colors:", screen.program.has256);
console.log("Supports true color:", screen.program.hasTrueColor);
Manual Terminal Override
Override detected terminal:
const screen = new Screen({
terminal: "xterm-256color", // Force specific terminal type
});
Input Handling
Keyboard Input
Handle keyboard events:
// Global keys
screen.key(["C-c", "q"], () => {
process.exit(0);
});
// Widget-specific keys
textbox.key(["enter"], () => {
form.submit();
});
// Raw key data
screen.on("keypress", (ch, key) => {
console.log("Pressed:", key.full);
});
Mouse Input
Enable mouse support:
const screen = new Screen({
mouse: true,
sendFocus: true,
});
box.on("click", (data) => {
console.log("Clicked at:", data.x, data.y);
});
box.on("wheeldown", () => {
box.scroll(1);
screen.render();
});
Raw Mode
Control raw terminal mode:
// Enable raw mode (default)
screen.program.setRaw(true);
// Disable raw mode
screen.program.setRaw(false);
// Restore mode on exit
process.on("exit", () => {
screen.program.setRaw(false);
});
Output Control
Writing to Terminal
Direct terminal output:
// Write via screen
screen.write("Hello\n");
// Write escape sequences
screen.program.write("\x1b[32mGreen text\x1b[0m\n");
// Position cursor
screen.program.move(10, 5); // Column 10, Row 5
screen.program.write("At position");
Screen Clearing
Clear screen methods:
// Clear entire screen
screen.clearRegion(0, screen.width, 0, screen.height);
// Clear specific region
screen.clearRegion(x, x + width, y, y + height);
// Full clear and reset
screen.program.clear();
screen.program.home();
Performance Optimization
Batch Updates
Minimize renders:
// ❌ Inefficient
for (let i = 0; i < 100; i++) {
boxes[i].setContent(`Item ${i}`);
screen.render();
}
// ✅ Efficient
for (let i = 0; i < 100; i++) {
boxes[i].setContent(`Item ${i}`);
}
screen.render(); // Single render
Throttle Rendering
For rapid updates:
let lastRender = 0;
const THROTTLE = 16; // ~60 FPS
function update() {
const now = Date.now();
if (now - lastRender > THROTTLE) {
screen.render();
lastRender = now;
}
}
Use Smart CSR
Enable for better performance:
const screen = new Screen({
smartCSR: true, // Uses scroll regions
fastCSR: true, // Even faster (may have artifacts)
});
Debugging
Debug Mode
Enable debugging:
const screen = new Screen({
debug: true,
log: "./debug.log",
});
// Log messages
screen.debug("Something happened");
Logging
Write to log file:
const screen = new Screen({
log: "./app.log",
});
// Logs to file
screen.log("Application started");
screen.log("User action:", action);
Dump Output
Save screen buffer:
const screen = new Screen({
dump: true, // Saves to ./blessed-${timestamp}.log
});
// Or manually
screen.dumpOutput("./screen-dump.txt");
Best Practices
1. Clean Exit
Always clean up:
function cleanup() {
screen.destroy();
}
process.on("exit", cleanup);
process.on("SIGINT", () => {
cleanup();
process.exit(0);
});
process.on("SIGTERM", () => {
cleanup();
process.exit(0);
});
2. Error Handling
Catch and display errors:
process.on("uncaughtException", (error) => {
// Clean up screen first
screen.destroy();
// Then display error
console.error("Uncaught error:", error);
process.exit(1);
});
process.on("unhandledRejection", (reason) => {
screen.destroy();
console.error("Unhandled rejection:", reason);
process.exit(1);
});
3. Resize Handling
Handle terminal resize:
screen.on("resize", () => {
// Re-layout widgets
sidebar.width = "30%";
content.width = "70%";
// Re-render
screen.render();
});
4. Use TypeScript
Get full type safety:
import { Screen, Box, type BoxOptions } from "@unblessed/node";
const options: BoxOptions = {
parent: screen,
top: "center",
left: "center",
width: "50%",
height: 10,
};
const box = new Box(options);
Next Steps
- Browser Platform - Running in browsers
- Platform Differences - Key differences between platforms
- Examples - Example applications