# blessed-contrib: building terminal dashboards with ascii art and JavaScript

> blessed-contrib extends blessed with charts, gauges, maps and log widgets for ascii/ansi terminals. It is a small Node.js library for developers who want a dashboard over ssh without a browser, and its layout model is the part worth understanding before you adopt it.

**yaronn/blessed-contrib** — Build terminal dashboards using ascii/ansi art and javascript

- Repository: https://github.com/yaronn/blessed-contrib
- Stars: 15,775 · Forks: 835
- Language: JavaScript
- License: MIT
- Published: 2026-09-21 · Updated: 2026-09-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/yaronn-blessed-contrib

## What blessed-contrib adds to a plain blessed screen

blessed gives you a screen, boxes, lists and text. It does not give you a line chart. blessed-contrib is the layer that fills that gap: the README describes it as extending blessed with custom drawille and other widgets. The widget list is concrete and finite: line chart, bar chart, stacked bar chart, map, gauge, stacked gauge, donut, LCD display, rolling log, picture, sparkline, table, tree and markdown. That list is the product.

The audience is narrow and worth stating plainly. This is for a developer who already writes JavaScript, already has Node.js running somewhere near the data, and wants the output to survive an ssh session, a tmux pane or a build log. The README's own framing is "friendly to terminals, ssh and developers". If your consumers expect a browser, this is the wrong shelf.

The repository also points at WOPR, described as a markup for creating terminal reports, presentations and infographics. That is a sibling project, not a replacement for the widget API, and it matters only if you would rather write markup than JavaScript.

## How a widget gets onto the screen: append first, then setData

The usage pattern is uniform across widgets, and the README repeats one warning with emphasis: you must append the widget to the screen before setting its data. The line chart example carries the comment "must append before setting data" on the same line as screen.append(line), and the bar chart example repeats it. Treat that ordering as part of the API contract rather than a stylistic preference.

Data flow is push-based and manual. You construct a widget with a config object, append it, and then call setData with a plain JavaScript object or array. There is no data source abstraction, no polling loop and no binding layer. The line chart takes an array of series, each with a title, an x array and a y array. The bar chart takes an object with titles and data arrays. The stacked bar chart takes barCategory, stackedCategory and a two-dimensional data array. The donut takes an array of objects carrying percent and label, with color optional and defaulting to green.

Rendering is explicit too. The example calls screen.render() at the end, and binds escape, q and C-c to process.exit(0) through screen.key. Nothing redraws on its own unless you write the timer that calls setData again. That is the whole architecture: blessed owns the terminal and the event loop, blessed-contrib owns the drawing of each widget into a region of the screen.

## Installing blessed-contrib and drawing a first line chart

The README asks for the latest stable Node.js LTS and names blessed as a peer dependency, so both packages go in the same install command:

```bash
npm install blessed blessed-contrib
```

If you would rather see the library working before writing anything, the README gives a four-step demo path. Run it from a clone, not from your own project directory:

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

You should see the dashboard shown in the repository's images, and pressing escape, q or C-c exits. The README states this works on Linux, OS X and Windows, and points Windows users at a separate prerequisites page before they start.

For your own project, the smallest useful program is a screen, one line chart and a key binding. The config keys below are the ones the README uses in its line chart example: style.line, style.text, style.baseline, xLabelPadding, xPadding, showLegend, wholeNumbersOnly and label.

```javascript
var blessed = require('blessed')
  , contrib = require('blessed-contrib')
  , screen = blessed.screen()
  , line = contrib.line(
      { style: { line: "yellow", text: "green", baseline: "black" }
      , xLabelPadding: 3
      , xPadding: 5
      , showLegend: true
      , wholeNumbersOnly: false
      , label: 'Title'})
  , data = { x: ['t1', 't2', 't3', 't4'], y: [5, 1, 7, 5] }
screen.append(line) //must append before setting data
line.setData([data])
screen.key(['escape', 'q', 'C-c'], function(ch, key) { return process.exit(0); })
screen.render()
```

Run that with node and you get a titled chart with a legend. Swap the two-element series from the README's multiple-lines example to check that the legend and the second color behave as expected. The repository ships examples for the awkward cases too: line-fraction.js, line-abbreviate.js, line-zoomed-in.js and line-start-above-zero.js all exist as separate files, which tells you the axis behaviour is configurable but not automatic.

## Where blessed-contrib stops: sizing, redraws and the terminal itself

The donut documentation is unusually honest about the ceiling. After explaining that setData accepts as many objects as you like and that they "will automatically resize and try to fit", the README adds that you will still be restricted to actual screen space. That sentence describes the whole library, not just the donut. Every widget is drawn into character cells, so a chart with forty series in an eighty-column terminal has nowhere to go.

There is also no retained state you can query. setData replaces what the widget draws; it is not an append or a windowed stream. If you want a scrolling time series, you keep the array yourself and hand the widget the slice you want shown. The rolling log widget is the exception in spirit, since a log is naturally append-shaped, but the README's widget list does not describe a retention policy for it.

Interactivity is thin. The README shows screen.key bindings for quitting, and the examples directory contains carousel.js, explorer.js and gauge-list.js, so some navigation exists in sample code. What the README does not document is a selection model, a focus API for widgets, or a way to attach a click handler to a bar. If your dashboard needs drill-down, you are writing that yourself on top of blessed.

The last push to the repository was on 2026-05-01, and the published version in package.json is 4.11.0. The test script is npm run lint, which runs eslint over lib. There is no test suite to lean on when you upgrade.

## blessed-contrib compared with Grafana and with a plain blessed table

The obvious alternative for a data dashboard is a browser tool such as Grafana. The difference is not features, it is where the rendering happens. Grafana runs a server, stores dashboards as configuration, and every viewer needs a browser and network access to that server. blessed-contrib runs inside the process that has the data, draws into the terminal you are already in, and ships as an npm dependency. If your data lives on a box you reach only over ssh, the browser tool needs a tunnel and the terminal library does not.

The cost is the other direction. Grafana gives you time-range pickers, alerting and shared dashboards without code. blessed-contrib gives you a setData call and whatever you build around it. Choosing it means accepting that every panel is a few lines of JavaScript you own.

The second alternative is not a product but a decision: skip the widgets and use plain blessed. A table of numbers in a blessed box is often enough, and it removes a dependency tree that includes drawille-canvas-blessed-contrib, map-canvas, picture-tuber, term-canvas and x256. If you only need a table and a log, the extra widgets are weight you will not use. The picture and map widgets in particular pull in rendering paths most dashboards never touch.

## Licence, upgrades and the maintenance picture

The package is MIT licensed, and the repository carries LICENSE.md at the top level. MIT is permissive: you can use, modify and redistribute the code, including in closed products, provided the copyright notice and licence text travel with it. That is the general shape of the licence, not legal advice for your situation, and the file in the repository is the authority.

Upgrade cost is mostly the peer dependency. blessed is listed in devDependencies at 0.1.54 and is not a runtime dependency of the package, so the version of blessed your application resolves is the one that matters. blessed-contrib's own dependency list is long and includes chalk at ^1.1.0, strip-ansi at ^3.0.0 and lodash at ~>=4.17.21. Those caret and range specifiers mean a fresh npm install can pull newer minor versions than the ones the author developed against.

The verification you have is npm run lint. There is no test script beyond it, so a dependency bump that changes drawing output will not be caught by the project's own tooling. Pin your lockfile, and after any upgrade of blessed or blessed-contrib, re-run the example that matches the widget you depend on. The examples directory is the closest thing to a regression suite this project ships.

## Conclusion

Adopt blessed-contrib if you already run Node.js on the machine that produces the data and you want the dashboard to live in the same terminal session as your logs. Do not adopt it if you need interactive drill-down, mouse-driven filtering, or a rendering target other than a terminal; it draws characters, and nothing in the README suggests that changes. Before writing any widget code, clone the repository and run node ./examples/dashboard.js to confirm that your terminal, your Node LTS version and, on Windows, the documented prerequisites all render the same output as the project's own example.

## FAQ

### What is blessed-contrib and how is it different from blessed?

blessed-contrib is a widget library that extends blessed, adding charts, gauges, maps, tables and other dashboard elements. blessed itself provides the screen, boxes, lists and text. The README states that blessed-contrib extends blessed with custom drawille and other widgets, and the install command asks for both packages together.

### How do I install blessed-contrib?

Install it alongside its peer dependency with npm install blessed blessed-contrib. The README asks for the latest stable Node.js LTS. To see it working first, clone the repository, run npm install inside the clone, and then run node ./examples/dashboard.js.

### Why does my blessed-contrib chart show nothing after I call setData?

The README marks the ordering explicitly: append the widget to the screen before setting its data. Both the line chart and bar chart examples carry the comment "must append before setting data" on the screen.append line. Calling setData before the append is the likely cause.

### Does blessed-contrib work on Windows?

The README states that it works on Linux, OS X and Windows, and directs Windows users to a separate prerequisites page before they begin. The prerequisites are not reproduced in the README itself, so follow that link rather than assuming a plain npm install is sufficient.

## Sources

- [Issues](https://github.com/yaronn/blessed-contrib/issues)
- [License: MIT](https://github.com/yaronn/blessed-contrib/blob/master/LICENSE)
- [README](https://github.com/yaronn/blessed-contrib/blob/master/README.md)
- [yaronn/blessed-contrib on GitHub](https://github.com/yaronn/blessed-contrib)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/yaronn-blessed-contrib
