blecsd
v0.6.0
Published
A modern, high-performance terminal UI library built on TypeScript and ECS architecture
Maintainers
Readme
blECSd
A high-performance terminal UI library built on TypeScript and bitECS.
blECSd provides a complete toolkit for building terminal applications: dashboards, file managers, system monitors, CLI tools, and games. It combines the performance of an Entity Component System with production-ready widgets and form controls.
Features
- 43 Widgets: Box, Panel, Tabs, List, Table, Tree, Terminal, Video, 3D Viewport, and more
- Form Controls: Textarea, Textbox, Checkbox, RadioButton, Switch, Select, ProgressBar, Form
- 41 Components: Position, Renderable, Focusable, Interactive, Animation, Collision, Camera, and more
- 21 Systems: Layout, Input, Render, Animation, Collision, SpatialHash, VisibilityCulling, and more
- Physics-based Animations: Velocity, acceleration, friction for smooth transitions
- Virtualized Rendering: Efficiently render 1000s of items
- State Machines: Built-in FSM support for complex UI state
Install
npm install blecsdQuick Start
Create a terminal app with a bordered panel, text, and keyboard input:
import {
createWorld, createScreenEntity, createBoxEntity,
createTextEntity, createListEntity, setText,
inputSystem, layoutSystem, renderSystem, outputSystem, cleanup,
enableInput, enableKeys,
} from 'blecsd';
// Set up the world and screen
const world = createWorld();
const screen = createScreenEntity(world, { width: 80, height: 24 });
// A bordered panel
const panel = createBoxEntity(world, {
x: 2, y: 1, width: 40, height: 12,
parent: screen,
border: { type: 1, top: true, bottom: true, left: true, right: true },
});
// Title text
createTextEntity(world, {
x: 4, y: 2, text: 'My Dashboard', parent: screen,
});
// A selectable list
const list = createListEntity(world, {
x: 4, y: 4, width: 36, height: 6, parent: screen,
});
// Enable keyboard input and run the update loop
enableInput(world, screen);
enableKeys(world, screen);
function tick(): void {
inputSystem(world);
layoutSystem(world);
renderSystem(world);
outputSystem(world);
}
const interval = setInterval(tick, 16);
process.on('SIGINT', () => { clearInterval(interval); cleanup(world); });Namespace Imports
blECSd organizes its API into discoverable namespace objects. Instead of importing dozens of individual functions, import a namespace and explore it with autocomplete:
import { position, scroll, content } from 'blecsd/components';
import { rope, colors, unicode } from 'blecsd/utils';
import { cursor, program, screen } from 'blecsd/terminal';
// Position operations
position.set(world, eid, 10, 5);
position.moveBy(world, eid, 1, 0);
position.zIndex.bringToFront(world, eid, siblings);
// Scroll control
scroll.by(world, eid, 0, 10);
scroll.toTop(world, eid);
// Text manipulation with rope data structure
const r = rope.create('Hello');
const modified = rope.insert(r, 5, ' World');
const text = rope.getText(modified);
// Color utilities
const hex = colors.rgbToHex(255, 100, 0);
const parsed = colors.parseColor('#ff6400');Import Tiers
| Tier | Import Path | Use Case |
|------|-------------|----------|
| Tier 1 | 'blecsd' | ~80 curated essentials (factories, systems, core helpers) |
| Tier 2 | 'blecsd/components', 'blecsd/utils', etc. | Full module access via namespaces |
| Tier 3 | Deep imports | Internal only |
Start with Tier 1 for prototyping, then use Tier 2 namespaces as your app grows. See the Export Patterns Guide for details.
Addon Packages
Specialized functionality is available as separate packages:
| Package | Description | Install |
|---------|-------------|---------|
| @blecsd/3d | 3D rendering with braille, halfblock, sixel, kitty backends | npm i @blecsd/3d |
| @blecsd/ai | LLM UI widgets: conversation, streaming markdown, token tracking | npm i @blecsd/ai |
| @blecsd/audio | Audio channel management and sound triggers | npm i @blecsd/audio |
| @blecsd/game | High-level createGame() API for terminal games | npm i @blecsd/game |
| @blecsd/media | GIF/PNG parsing, ANSI rendering, image/video widgets | npm i @blecsd/media |
Each addon package also provides namespace objects for discoverability:
// 3D math via namespaces
import { vec3, mat4, projection } from '@blecsd/3d';
const v = vec3.add(vec3.create(1, 0, 0), vec3.create(0, 1, 0));
const mvp = mat4.multiply(projection.perspective(60, 1.5, 0.1, 100), viewMatrix);
// AI widgets via namespaces
import { conversation, tokenTracker } from '@blecsd/ai';
conversation.addMessage(state, { role: 'user', content: 'Hello' });
// Media via namespaces
import { gif, png } from '@blecsd/media';
const frames = gif.parse.parseGIF(buffer);Addon packages also support subpath imports for tree-shaking:
import { vec3Add, vec3Cross } from '@blecsd/3d/math';
import { parseGIF } from '@blecsd/media/gif';Widgets
| Widget | Description | |--------|-------------| | BarChart | Bar chart visualization | | BigText | Large ASCII art text | | Box | Base container with borders, padding, content | | Button | Clickable button with hover/focus states | | Checkbox | Boolean toggle with customizable characters | | FileManager | File browser with directory navigation | | Form | Form field management, validation, submit | | Gauge | Circular/radial gauge display | | HoverText | Tooltip/hover text display | | Image | Image rendering with various formats | | Layout | Flex/grid layout container | | Line | Horizontal/vertical separator | | LineChart | Line chart visualization | | List | Selectable list with keyboard/mouse support | | Listbar | Horizontal navigation bar | | ListTable | Table-style list display | | Loading | Loading indicator with spinner | | Log | Scrollable log viewer | | Message | Message box with buttons | | Modal | Modal dialog overlay | | Panel | Box with title bar, collapsible, close button | | ProgressBar | Progress indicator, horizontal/vertical | | Prompt | Input prompt dialog | | Question | Question dialog with yes/no buttons | | RadioButton | Single selection from group | | ScrollableBox | Container with scroll support | | ScrollableText | Scrollable text area | | Sparkline | Sparkline chart visualization | | SplitPane | Split pane container with resize | | StreamingText | Text display with typewriter effect | | Switch | Toggle switch control | | Table | Data table with headers, columns, sorting | | Tabs | Tabbed container with keyboard navigation | | Terminal | ANSI terminal emulator with PTY support | | Text | Text display with alignment, wrapping | | Textarea | Multi-line text editor | | Textbox | Single-line text input | | TextEditing | Text editing utilities | | Toast | Toast notification popup | | Tree | Hierarchical tree view with expand/collapse | | Video | Video playback widget | | Viewport3d | 3D scene renderer | | VirtualizedList | Efficient list for large datasets |
Components
blECSd provides ECS components that work with any bitECS world. Each component has a corresponding namespace object for typed access:
import { position, content, list, scroll } from 'blecsd/components';
position.set(world, eid, 10, 5); // set x, y
content.set(world, eid, 'Hello'); // set text content
list.select(world, eid, 2); // select item at index
scroll.toBottom(world, eid); // scroll to end| Component | Namespace | Purpose |
|-----------|-----------|---------|
| Animation | animation | Frame-based sprite animations |
| Border | border | Box borders (single, double, rounded, bold, ascii) |
| Camera | camera | Viewport, target following, bounds |
| Collision | collision | AABB/circle collision detection, layers, triggers |
| Content | content | Text content, alignment, wrapping, tag parsing |
| Dimensions | dimensions | Width, height, min/max constraints, percentages |
| Focusable | focus | Keyboard focus, tab order |
| Hierarchy | hierarchy | Parent-child relationships, traversal |
| List | list | List widget state, selection, virtualization |
| Position | position | X/Y coordinates, z-index, absolute positioning |
| Renderable | renderable | Colors, visibility, dirty tracking |
| Scrollable | scroll | Scroll position, scrollbars, virtual viewport |
| Table | table | Table state, columns, rows, sorting |
| TextInput | textInput | Text input, cursor, selection, validation |
| Velocity | velocity | Movement with speed, friction, max speed |
See API Reference for the complete list of all 41 components.
Systems
| System | Purpose | |--------|---------| | animationSystem | Update sprite animations | | behaviorSystem | Execute behavior trees | | cameraSystem | Update camera following target | | collisionSystem | Detect and resolve collisions | | dragSystem | Handle drag and drop | | focusSystem | Manage focus, tab navigation | | frameBudget | Frame time profiling and budget management | | inputSystem | Process keyboard/mouse input | | layoutSystem | Calculate positions, dimensions | | movementSystem | Apply velocity to position | | outputSystem | Write buffer to terminal | | panelMovement | Handle panel drag/resize | | particleSystem | Update particle effects | | renderSystem | Render entities to screen buffer | | smoothScroll | Smooth scrolling animations | | spatialHash | Spatial partitioning for collision | | stateMachineSystem | Process state machine transitions | | tilemapRenderer | Render tilemap layers | | virtualizedRenderSystem | Efficient rendering for large datasets | | visibilityCulling | Frustum/viewport culling | | workerPool | Background task processing |
Library Design
blECSd is a library, not a framework:
- Components work standalone: Import them into any bitECS world
- No required update loop: All systems are callable functions
- Mix and match: Use our input parsing with your rendering, or vice versa
- You own the world: Functions take
worldas a parameter; we never hold global state
import { createWorld, addEntity, layoutSystem, renderSystem } from 'blecsd';
import { position, renderable } from 'blecsd/components';
const world = createWorld();
const eid = addEntity(world);
// Use namespace helpers for typed access
position.set(world, eid, 10, 5);
renderable.show(world, eid);
// Call systems when you want
layoutSystem(world);
renderSystem(world);Use Cases
- Dashboards: System monitors, log viewers, status displays
- File Managers: Tree views, virtualized lists, panels
- CLI Tools: Forms, menus, progress indicators
- Dev Tools: Debug panels, profilers, inspectors
- Games: Roguelikes, text adventures, puzzle games
- AI Interfaces: LLM chat, streaming output, token tracking (via @blecsd/ai)
- 3D Terminals: Wireframe viewers, model inspectors (via @blecsd/3d)
Comparison
| Feature | blECSd | Ink | blessed | Textual | |---------|--------|-----|---------|---------| | Architecture | ECS + PackedStore (data-oriented) | React (component) | Class-based | Widget classes | | Language | TypeScript | TypeScript/JSX | JavaScript | Python | | Widgets | 43 built-in | Few built-in | Many built-in | Many built-in | | Animation | Physics-based | Manual | Manual | CSS-like | | Virtualization | Built-in | Manual | Manual | Built-in | | Game support | First-class | Limited | Limited | Limited |
Choose blECSd if you want data-oriented design, physics-based animations, or game development support. Choose Ink for React-style development. Choose Textual for Python projects.
Documentation
Getting Started
- Installation: Requirements, terminal compatibility, setup
- Core Concepts: ECS, scheduler, events
- Hello World: Your first blECSd application
API Reference
- API Reference: Components, widgets, systems, terminal I/O
- Export Patterns: Import tiers, namespaces, module map
- Terminal Widget: ANSI rendering and PTY shell support
Guides
- Guides: Animations, forms, layouts, and more
- Error Handling: Error boundaries and recovery
- Testing Guide: Unit and integration testing
- Performance Optimization: Profiling and optimization
- Migration Guide: Migrating from other libraries
- Keyboard Shortcuts: Custom keybindings
Examples
- Examples Repository: File manager, multiplexer, system monitor, ANSI viewer, telnet server, and more
Development
pnpm install
pnpm test
pnpm lint
pnpm buildBenchmarking
Run performance benchmarks to measure system performance:
# Run all benchmarks
pnpm bench
# Run CI benchmarks (fast subset for regression detection)
pnpm bench:ci
# Run real-world scenario benchmarks
pnpm bench:scenarios
# Update performance baseline
pnpm bench:update-baseline
# Check for performance regressions (vs baseline)
pnpm bench:check-regressionThe CI automatically checks for performance regressions on pull requests. If any benchmark regresses by more than 20%, the build will fail.
License
MIT
