RepoPilotOpen in app →

yaronn/blessed-contrib

Build terminal dashboards using ascii/ansi art and javascript

Mixed

Mixed signals — read the receipts

weakest axis
Use as dependencyMixed

no tests detected; no CI workflows detected

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 5d ago
  • 35+ active contributors
  • Distributed ownership (top contributor 27% of recent commits)
  • MIT licensed
  • No CI workflows detected
  • No test directory detected
What would change the summary?
  • Use as dependency MixedHealthy if: add a test suite

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Earn the “Healthy” badge

Current signals for yaronn/blessed-contrib are Mixed. The embed flow is reserved for repos showing Healthy signals — the rest stay informational on this page so we're not putting a public call-out on your README. Address the items in the What would change the summary? dropdown above, then return to grab the embed code.

Common quick wins: green CI on default branch, no Critical CVEs in dependencies, recent commits on the default branch, a permissive license, and a published README.md with a quickstart.

Onboarding doc

Onboarding: yaronn/blessed-contrib

Generated by RepoPilot · 2026-05-06 · Source

Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/yaronn/blessed-contrib shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

Verdict

WAIT — Mixed signals — read the receipts

  • Last commit 5d ago
  • 35+ active contributors
  • Distributed ownership (top contributor 27% of recent commits)
  • MIT licensed
  • ⚠ No CI workflows detected
  • ⚠ No test directory detected

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live yaronn/blessed-contrib repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/yaronn/blessed-contrib.

What it runs against: a local clone of yaronn/blessed-contrib — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in yaronn/blessed-contrib | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 35 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>yaronn/blessed-contrib</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of yaronn/blessed-contrib. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/yaronn/blessed-contrib.git
#   cd blessed-contrib
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of yaronn/blessed-contrib and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "yaronn/blessed-contrib(\\.git)?\\b" \\
  && ok "origin remote is yaronn/blessed-contrib" \\
  || miss "origin remote is not yaronn/blessed-contrib (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift — was MIT at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "index.js" \\
  && ok "index.js" \\
  || miss "missing critical file: index.js"
test -f "index.d.ts" \\
  && ok "index.d.ts" \\
  || miss "missing critical file: index.d.ts"
test -f "lib/widget/canvas.js" \\
  && ok "lib/widget/canvas.js" \\
  || miss "missing critical file: lib/widget/canvas.js"
test -f "lib/layout/grid.js" \\
  && ok "lib/layout/grid.js" \\
  || miss "missing critical file: lib/layout/grid.js"
test -f "lib/widget/charts/line.js" \\
  && ok "lib/widget/charts/line.js" \\
  || miss "missing critical file: lib/widget/charts/line.js"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 35 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~5d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/yaronn/blessed-contrib"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

blessed-contrib is a Node.js library that extends the blessed terminal UI framework with custom dashboard widgets (line charts, bar charts, gauges, tables, maps, etc.) rendered using ASCII/ANSI art and Drawille canvas. It enables developers to build data dashboards and terminal applications with zero graphics libraries, working seamlessly over SSH and in plain text terminals. Simple flat structure: lib/ contains the core widget implementations and utilities; examples/ provides runnable demos for each widget type (bar.js, line.js, gauge.js, etc.) plus inline-data variants showing data-only usage; docs/ holds images and fonts for documentation. index.js is the main entry point that exports the widget constructors. No monorepo structure—single npm package with all widgets bundled.

Who it's for

Backend engineers, DevOps practitioners, and SREs who need to build monitoring dashboards, system metrics displays, and terminal-based UIs without heavy dependencies. Also useful for developers creating CLI tools that need rich visualization capabilities in resource-constrained environments (headless servers, remote access).

Maturity & risk

Mature and actively maintained. At v4.11.0 with stable API, comprehensive examples in examples/ directory, and ESLint setup. Uses blessed 0.1.54 as peer dependency (itself well-established). No visible CI/CD config in file list and no test directory suggests testing is minimal, but the project has been battle-tested (evidenced by multiple contributors and npm adoption). Production-ready for terminal dashboards but not continuously integrated.

Moderate risk: single primary maintainer (Yaron Naveh), no automated test suite visible (no test/ or tests/ directory despite 64KB of JavaScript), and dependencies on several single-author packages (drawille-canvas-blessed-contrib, picture-tuber, term-canvas). Dependency chain is reasonable (~12 direct deps) but includes older packages (chalk 1.1.0, marked 4.0.12). Last commit age unknown from data, but project structure suggests active maintenance.

Active areas of work

Based on file list, active maintenance of widgets and examples. Recent additions suggest focus on inline-data examples (examples/inline-data/ directory) for easier adoption. No specific PR/milestone data visible, but the presence of comprehensive examples and TypeScript typings (index.d.ts) indicates recent modernization effort.

Get running

git clone https://github.com/yaronn/blessed-contrib.git
cd blessed-contrib
npm install
node ./examples/dashboard.js

Daily commands:

npm install
node ./examples/dashboard.js

For development linting: npm run lint or npm run lint:fix (uses ESLint with standard config).

Map of the codebase

  • index.js — Entry point that exports all widgets and layout components; required reading to understand what's exposed to consumers
  • index.d.ts — TypeScript definitions for the entire public API; essential for understanding type contracts and supported APIs
  • lib/widget/canvas.js — Base canvas abstraction using drawille for ASCII art rendering; all chart widgets depend on this for drawing primitives
  • lib/layout/grid.js — Core grid layout system for composing dashboard layouts; fundamental pattern for all example dashboards
  • lib/widget/charts/line.js — Line chart implementation demonstrating the most common widget pattern and data update mechanisms
  • package.json — Declares blessed as core peer dependency and entry point; critical for understanding runtime requirements

Components & responsibilities

  • Grid Layout (blessed Box) — Divides screen into logical cells and assigns widgets to regions; coordinates z-order and focus
    • Failure mode: Overlapping widgets or collapsed cells if row/col span exceeds bounds; no bounds checking
  • Canvas (Base Class) (drawille, blessed.Box) — Manages drawille canvas instance, coordinate transforms, and color palette; shared by all chart widgets
    • Failure mode: Coordinate overflow if data exceeds canvas bounds; no clipping implemented
  • Line Chart (Canvas, drawille) — Converts numeric data series into polyline paths; handles zooming, scaling, abbreviation, and multi-series rendering
    • Failure mode: Y-axis scale explosion with extreme outliers; no robust min/max detection
  • Table Widget (blessed.Box, blessed events) — Renders row/col data as aligned ASCII table; supports highlighting and keyboard navigation
    • Failure mode: Column width overflow if content exceeds allocated space; truncation not always clean
  • Log Widget (blessed.Box, blessed ScrollableBox) — Appends text lines with scrollback; manages buffer and viewport position
    • Failure mode: Unb

How to make changes

Add a new chart widget

  1. Create widget file in lib/widget/ or lib/widget/charts/ extending the canvas base class (lib/widget/charts/line.js)
  2. Implement setData(data) method to accept and store data, and render() to draw using canvas primitives (lib/widget/charts/line.js)
  3. Export the widget class from index.js alongside other widgets (index.js)
  4. Add TypeScript definitions to index.d.ts with constructor params and public methods (index.d.ts)
  5. Create example file in examples/ demonstrating usage with sample data (examples/line.js)

Build a new dashboard layout

  1. Create grid instance specifying rows, columns, and screen dimensions (examples/dashboard.js)
  2. Attach widgets to grid cells using grid.set(row, col, rowSpan, colSpan, widget) (lib/layout/grid.js)
  3. Call widget.setData(data) on intervals (e.g. setInterval) to update charts (examples/dashboard.js)
  4. Set screen.key bindings to handle quit, refresh, or navigation events (examples/dashboard.js)

Extend an existing widget with new options

  1. Add constructor parameter to widget constructor accepting new option object (lib/widget/table.js)
  2. Store option in instance and use it in render() or helper methods (lib/widget/table.js)
  3. Update index.d.ts to include new optional property in widget interface (index.d.ts)
  4. Add example showing new option usage in examples/ subdirectory (examples/table-color.js)

Why these technologies

  • blessed — Terminal UI framework providing low-level cursor control, key bindings, and event handling; foundation for all widget interaction
  • drawille — Provides Braille characters and block drawing primitives for smooth line/bar rendering in ASCII; enables chart quality comparable to GUI
  • chalk — Lightweight ANSI color abstraction for cross-platform terminal color support without dealing with escape codes
  • ansi-term — Terminal capability detection and ANSI sequence generation for portability across different terminal emulators

Trade-offs already made

  • Pure ASCII/ANSI rendering instead of pixel graphics

    • Why: Enables SSH-friendly dashboards that work in any terminal without requiring graphics support or special fonts
    • Consequence: Limited visual fidelity and resolution compared to GUI; chart density and label placement require careful tuning
  • Synchronous widget rendering on data updates

    • Why: Simple, predictable update model; no async state management complexity
    • Consequence: Heavy data loads or complex widgets may cause noticeable frame drops; not suitable for sub-100ms update intervals
  • No built-in state management or event bus

    • Why: Keeps framework minimal and unfenced; users have full control over data flow
    • Consequence: Larger example applications become repetitive; developers must implement their own data coordination
  • Canvas inherits from blessed.Box rather than composition

    • Why: Deep integration with blessed rendering pipeline; direct access to screen methods
    • Consequence: Tight coupling to blessed internals; harder to test in isolation or port to other backends

Non-goals (don't propose these)

  • Real-time animation or sub-frame-rate updates (not designed for 60fps dashboards)
  • Web-based rendering or browser compatibility (terminal-only)
  • High-level state management (users provide data)
  • Native mouse support (keyboard-driven interaction primary)

Traps & gotchas

Terminal compatibility: some widgets (especially those using Drawille canvas like line charts) require a terminal that supports Unicode block/braille characters; may render incorrectly on Windows without special setup (README references Windows pre-requisites blog post). Peer dependency on blessed: blessed must be installed separately (npm install blessed blessed-contrib); mismatched versions can cause rendering issues. No test suite: changes lack automated verification; manual testing via examples/ is the primary validation method. Memory streams: project uses both memory-streams and memorystream packages (potentially redundant); can cause confusion when debugging stream behavior.

Architecture

Concepts to learn

  • Drawille / Unicode Block Graphics — blessed-contrib renders smooth curves and filled areas in terminals using Drawille (4×2 Braille Unicode characters), allowing line charts and maps to display without pixel-based graphics; understanding this is critical for debugging rendering or contributing canvas-based widgets
  • ANSI/ASCII Art and Terminal Color Codes — All visual output in blessed-contrib uses ANSI escape codes for colors and styling; contributors must understand these sequences to customize widget appearance or add new color schemes
  • Blessed Element Hierarchy & Layout System — blessed-contrib widgets inherit from blessed.Element and are composed via blessed's box/grid layout engine; understanding parent-child relationships and render cycles is essential for extending widgets or debugging layout bugs
  • Data Binding & Real-time Updates (setData Pattern) — blessed-contrib widgets use a setData(dataObject) pattern to update chart data and trigger re-renders; this push-based model is different from React-style declarative UI and must be understood for building dynamic dashboards
  • Terminal Canvas / Canvas API Emulation — blessed-contrib uses term-canvas and drawille-canvas to emulate a 2D canvas API in the terminal; widgets like line and bar charts draw shapes to this virtual canvas which is then rasterized to terminal cells
  • Key Binding & Event Handling in Blessed — Terminal dashboards need keyboard interaction; blessed provides screen.key() for listening to keypresses; contributors must understand event propagation if adding interactivity (e.g., scrolling tables, drill-down navigation)
  • Stream-based Rendering (Memory Streams) — Some widgets (markdown, table) use memory-streams to capture output before rendering to terminal; understanding stream composition helps debug widgets that consume piped data or render text-heavy content

Related repos

  • chjj/blessed — Direct parent library—blessed-contrib extends blessed's box/element system; understanding blessed's source is essential for debugging rendering issues
  • yaronn/wopr — Companion project by the same author; WOPR is a markup language for creating terminal reports/presentations using blessed-contrib widgets
  • madbence/node-drawille — Underlying Drawille canvas implementation; blessed-contrib uses drawille-canvas-blessed-contrib fork to draw vector graphics (lines, curves) in terminal using Unicode blocks
  • markedjs/marked — Markdown parser used by blessed-contrib's markdown widget; dependency for rendering markdown in terminal dashboards
  • gizak/termui — Similar Go-based terminal dashboard library; reference for architectural patterns in terminal UI widget design if exploring cross-language patterns

PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add TypeScript definitions for all widget classes in lib/widget

The repo has index.d.ts but it's incomplete. The TypeScript definitions don't cover all widget implementations found in lib/widget/charts/ and other widget subdirectories. This would improve IDE autocomplete and type safety for TypeScript users, reducing integration friction.

  • [ ] Audit index.d.ts against actual exported widgets in lib/widget/canvas.js and lib/widget/charts/*.js
  • [ ] Add complete interface definitions for Bar, Line, and other chart classes with their constructor options and methods
  • [ ] Add definitions for layout classes (Grid, Carousel) from lib/layout/*.js
  • [ ] Test definitions against examples/inline-data/*.js by adding tsc --noEmit to test script

Create unit test suite for lib/utils.js and lib/layout/ modules

The repo has only a lint test (npm test runs eslint). There are no unit tests for core utility functions or layout logic. With multiple contributors and complex chart/layout rendering, unit tests would catch regressions and make refactoring safer.

  • [ ] Set up Jest or Mocha test framework in devDependencies
  • [ ] Create test/utils.test.js covering functions exported from lib/utils.js
  • [ ] Create test/layout.test.js covering Grid and Carousel classes from lib/layout/grid.js and lib/layout/carousel.js
  • [ ] Add 'test' script to package.json that runs tests (not just lint) and update CI if added

Add GitHub Actions workflow for automated testing and releases

The repo has no CI/CD configuration visible (.github/workflows missing). With devDependencies already configured and examples provided, automating lint checks and version tagging on releases would reduce manual errors and improve contributor confidence.

  • [ ] Create .github/workflows/test.yml to run 'npm run lint' and any new test suite on push/PR
  • [ ] Create .github/workflows/publish.yml to automatically publish to npm on version tags
  • [ ] Verify workflows can install blessed (peer dependency in examples) and run successfully
  • [ ] Document CI status in README.md with badge

Good first issues

  • Add test suite for lib/bar.js and lib/line.js using a terminal testing framework like blessed-test-harness; currently no test/ directory exists despite 64KB of widget code
  • Create TypeScript usage examples in examples/ (currently only index.d.ts exists but no .ts example files); pair with documentation on setup steps for TypeScript projects
  • Document API contract for all setData() methods across widgets (gauge, donut, table, etc.) in a unified reference page or JSDoc comments in lib/, as current docs show only usage examples, not parameter shapes

Top contributors

Recent commits

  • 45a7db6 — docs: update to include a minimum supported version (#233) (lirantal)
  • ecd48d9 — fix: upgrade to marked@4 fixing security issues (lirantal)
  • 410c6d7 — 4.10.1 (lirantal)
  • aeb95f9 — fix(tree): add type declaration (#216) (chinggg)
  • d981f1f — fix(tree): now passes selectFg and selectBg options in tree, to list. (#196) (cwingrav)
  • 2ea98c6 — feat: add support for displaying arbitrary numbers in donuts core text (#214) (lirantal)
  • 48ef9c9 — 4.9.0 (lirantal)
  • e8eb98a — fix: update deps (lirantal)
  • df3b782 — 4.8.21 (lirantal)
  • 0414fd7 — fix(sparkline): incorrect types for setData (#206) (Lucas Bento)

Security observations

The blessed-contrib codebase has moderate security concerns primarily stemming from outdated and potentially vulnerable dependencies. Critical issues include chalk 1.1.0 (2015 release), ESLint 5.11.0 (2019

  • High · Outdated and Vulnerable Dependency - marked — package.json - marked dependency. The package uses 'marked' version ^4.0.12. While this is a recent version, marked has had multiple security vulnerabilities in the past related to XSS and injection attacks. The dependency should be regularly audited and updated. Fix: Run 'npm audit' to check for known vulnerabilities. Update to the latest patched version of marked and enable security updates. Consider using npm audit in CI/CD pipeline.
  • High · Vulnerable Dependency - chalk 1.1.0 — package.json - chalk dependency. chalk version ^1.1.0 is significantly outdated (released in 2015). Modern versions are 4.x or 5.x. Older versions may have unpatched security vulnerabilities. Fix: Update chalk to the latest stable version (^5.0.0 or later). Review changelog for breaking changes before updating.
  • Medium · Vulnerable Dependency - strip-ansi 3.0.0 — package.json - strip-ansi dependency. strip-ansi version ^3.0.0 is outdated (last updated in 2016). Current versions are at 6.x or 7.x. May contain unpatched vulnerabilities. Fix: Update strip-ansi to version ^7.0.0 or later. Check for any API changes before upgrading.
  • Medium · Vulnerable Dependency - ESLint 5.11.0 — package.json - eslint devDependency. ESLint version ^5.11.0 is outdated (released in 2019). Current versions are 8.x or 9.x. Development dependency with potential security issues. Fix: Update ESLint to version ^8.0.0 or latest 9.x. Update related ESLint plugins to compatible versions.
  • Medium · Vulnerable Dependency - blessed 0.1.54 — package.json - blessed devDependency. blessed version 0.1.54 is a legacy version (no longer maintained actively). This is a critical dependency for terminal UI rendering and may have unpatched vulnerabilities. Fix: Verify if blessed is still actively maintained. Consider alternative maintained libraries or evaluate patching critical issues. Run 'npm audit' to identify specific CVEs.
  • Medium · Loose Version Constraints for Critical Dependencies — package.json - dependencies with loose constraints. Several dependencies use loose version constraints (>=, ~>) that may allow installation of vulnerable versions: ansi-term (>=0.0.2), drawille-canvas-blessed-contrib (>=0.1.3), map-canvas (>=0.1.5), x256 (>=0.0.1). This can lead to unexpected installations of vulnerable versions. Fix: Use more restrictive version constraints. Replace >= with caret (^) or tilde (~) operators. Example: '>= 0.0.2' should be '^0.0.2' or pinned to a specific tested version.
  • Low · Potential XSS in Terminal Rendering — lib/widget/markdown.js, lib/widget/ (general). The library renders markdown (via marked) and terminal content. While this is a terminal application (not a web application), improper escaping of user-supplied content in markdown or other input could lead to terminal injection or ANSI escape code injection. Fix: Ensure all user-supplied input to markdown parser and terminal rendering functions is properly sanitized. Use marked's options to disable potentially dangerous features. Validate and escape ANSI codes.
  • Low · Missing Security Headers Configuration — README.md, docs/. While this is a terminal UI library (not web-based), there is no security policy documentation or guidelines for secure usage patterns. Fix: Add a SECURITY.md file documenting security best practices for users of this library. Include guidance on input validation and safe usage patterns.

LLM-derived; treat as a starting point, not a security audit.

Where to read next


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Mixed signals · yaronn/blessed-contrib — RepoPilot