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

chartscii

v4.0.0

Published

awesome ascii charts

Readme

Chartscii

Beautiful ASCII charts for your terminal.

Render your data as beautiful ASCII charts
with full color, gradients, stacked bars, animations, and rich text, straight from your terminal.

npm npm downloads license


What's new in v4

  • 5 new chart typesline, step, scatter, candlestick, status
  • Stacked charts — multi-segment bars with per-segment colors
  • Gradients — horizontal, vertical, and diagonal, with reverse direction
  • Auto color — cycle palettes without writing color code
  • Animations — built-in easings and frame stepping
  • Rich text labels — bold, italic, underline, invert via styl3
  • Title & alignment — full positional control over titles and bars
  • Relative scaling — emphasize differences in tightly clustered values

Table of contents


Installation

npm install chartscii

Looking for the CLI? Check out chartscii-cli.


Quick start

import Chartscii from "chartscii";

const data = Array.from({ length: 10 }, (_, i) => i + 1);

const chart = new Chartscii(data, {
  width: 50,
  theme: "pastel",
  barSize: 2,
  orientation: "vertical",
  color: "pink",
});

console.log(chart.create());

That's it — three lines of data, one chart object, and a single console.log call.


Chart types

Set the type option to switch the renderer. Every chart type shares the core options (width, height, title, theme, color, naked, …) and adds its own visual model and a few type-specific knobs.

| Type | Best for | Key options | |---|---|---| | bar (default) | categorical comparisons, totals, rankings | orientation, alignBars, stackColors | | line | trends over time, multiple series | points, pointChar, legend | | step | state changes between samples | variant: 'sharp' \| 'smooth', points | | scatter | sparse points, distributions | pointChar, colorLabels | | candlestick | OHLC market data | color: [bull, bear], barSize | | status | dashboards, health grids | color: { key → color }, grid or row mode |

Bar (default)

The classic chartscii renderer. Stacked, oriented, and aligned to taste.

const chart = new Chartscii([10, 25, 40, 15], {
  type: "bar",
  orientation: "vertical",
  color: "gradient(cyan,purple)",
});

Line

Smooth 45° polyline through your data. Single- or multi-series, with optional point markers.

const chart = new Chartscii(data, {
  type: "line",
  width: 80,
  height: 12,
  color: "gradient(pink,cyan)",
  fill: "░",            // optional area fill below the line
  fillColor: "pink",
  points: true,         // draw a marker at each data point
  pointChar: "◈",       // override the marker char
});

Multi-series: pass InputData[][] and an array of colors.

const chart = new Chartscii(seriesData, {
  type: "line",
  width: 150,
  color: ["gradient(pink,cyan)", "gradient(orange,yellow)", "red"],
  legend: { values: ["Q1", "Q2", "Q3"], position: "top", align: "right" },
});

Slopes that need more horizontal space than the natural 45° span are clustered into a single contiguous diagonal followed by a flat plateau, so peaks render as sharp ╱╲ rather than a jagged staircase.

Step

Same idea as line, but transitions are right-angle steps — perfect for state that's piecewise-constant between samples.

const chart = new Chartscii(data, {
  type: "step",
  width: 80,
  variant: "smooth",   // 'sharp' (┌┐└┘) or 'smooth' (╭╮╰╯)
  color: "auto",
  points: true,
});

Multi-series and legend work exactly like line:

Scatter

Just the points — no connecting line. Each marker can be a different color.

const chart = new Chartscii(data, {
  type: "scatter",
  width: 100,
  color: "auto",          // cycle the palette per point
  pointChar: "◈",         // default '●'
  colorLabels: true,      // tint x-axis labels with their point's color
});

Per-point overrides win over the series color, so { value, color } colors that specific marker:

Candlestick

OHLC bars with bullish / bearish coloring. Each input point's value is a 4-tuple [open, high, low, close].

const chart = new Chartscii(month, {
  type: "candlestick",
  width: 100,
  height: 18,
  color: ["#4caf50", "#ef5350"],   // [bullish, bearish]
  // color: "auto",                 // also valid — uses theme bull/bear pair
  title: { text: "BTC/USD — 30d", align: "center", color: "gradient" },
  legend: { position: "top", align: "right" },
});

barSize controls the body width (default 1 — a one-cell-wide candle); padding controls the gap between candles. Doji candles (open == close) render as .

Status

A grid (or row layout) of colored cells — perfect for dashboards, host health, build matrices, log heatmaps, and so on. Each cell's value is a status key (number or string) looked up in the color map.

// Grid mode — one cell per input
const chart = new Chartscii(fleet, {
  type: "status",
  width: 100,
  barSize: 5,
  padding: 1,
  color: {
    0: "red",      // down
    1: "green",    // ok
    2: "yellow",   // warning
    3: "#888",     // maintenance
  },
  legend: { values: ["down", "ok", "warning", "maintenance"] },
});

Pass value: number[] (or string[]) on any input point to switch into row mode — each input becomes a row labelled on the left, with its array values rendered as colored cells along the x-axis:

const data: InputData[] = [
  { value: [1, 1, 0, 1, 2, 1, 1], label: "web1" },
  { value: [1, 0, 0, 1, 1, 1, 2], label: "web2" },
  { value: [1, 1, 1, 1, 1, 1, 1], label: "web3" },
];

Mixed input is allowed — scalar values become single-cell rows. Per-point color overrides apply to every cell on that row.


Input formats

Simple numbers

const chart = new Chartscii([1, 2, 3, 4, 5]);

Chart points

const data = [
  { label: "Sales", value: 100, color: "green" },
  { label: "Returns", value: 25, color: "red" },
  { label: "Pending", value: 40, color: "yellow" },
];

| Property | Type | Description | |---|---|---| | label | string | Bar / point label (defaults to value) | | value | number | number[] | string | Single, stacked, OHLC, or status key — see below | | color | string | string[] | Color or per-segment colors |

Chart-type-specific value shapes

| Chart type | value shape | |---|---| | bar, line, step, scatter | number | | Stacked bar | number[] or { value, color? }[] | | candlestick | [open, high, low, close] (number tuple) | | status (grid mode) | number | string (status key) | | status (row mode) | number[] | string[] (one cell per entry) |

Multi-series (line / step / scatter)

Pass InputData[][] — one inner array per data point, with one entry per series:

const data: InputData[][] = months.map((m, i) => [
  { value: salesA[i], label: m },   // series 1
  { value: salesB[i], label: m },   // series 2
]);

Styling

Colors & gradients

color accepts a few different shapes depending on the chart type:

// Any chart — a single color, a gradient, or "auto" palette cycling
color: "green"
color: "gradient(pink,cyan)"
color: "auto"

// Multi-series line / step / scatter — one entry per series
color: ["gradient(pink,cyan)", "gradient(orange,yellow)", "red"]

// Candlestick — [bullish, bearish]
color: ["green", "red"]

// Status — map from status key to color
color: { 0: "red", 1: "green", 2: "yellow", 3: "#888" }
color: { ok: "green", warning: "yellow", error: "red" }

Auto color

Cycle through a curated palette automatically — no manual color assignments needed.

const data = Array.from({ length: 9 }, (_, i) => ({
  value: (i + 1) * 5,
  label: `item ${i + 1}`,
}));

const chart = new Chartscii(data, {
  width: 50,
  color: "auto",
  colorLabels: true,
  valueLabels: true,
  theme: "pastel",
});

Gradient directions

// Horizontal — left to right
color: "gradient(red,yellow,green)";

// Vertical — top to bottom
color: "gradient(purple,cyan:vertical)";

// Diagonal — corner to corner
color: "gradient(pink,orange,yellow:diagonal)";

// Any direction can be reversed
color: "gradient(purple,cyan:vertical:reverse)";
color: "gradient(pink,orange,yellow:diagonal:reverse)";
const chart = new Chartscii(data, {
  width: 60,
  title: {
    text: "Gradient Aligned Right",
    align: "right",
    color: "gradient",
    padding: [1, 0],
  },
  orientation: "vertical",
  color: "gradient(pink,cyan)",
  theme: "beach",
  fill: "░",
  fillColor: "auto",
  padding: 1,
  valueLabels: true,
});

Reverse gradient

const chart = new Chartscii(data, {
  orientation: "vertical",
  barSize: 10,
  fill: "▒",
  fillColor: "auto",
  colorLabels: true,
  color: "gradient(pink,cyan:reverse)",
  theme: "pinkish",
  percentage: true,
});

Themes

Chartscii integrates with styl3 for 20+ built-in color themes. Just set the theme name:

const chart = new Chartscii(data, { theme: "lush" });

| Theme | Vibe | |---|---| | pastel | Soft, muted tones | | lush | Vibrant, saturated | | beach | Warm coastal palette | | neon | Electric, bright | | sunset | Warm orange/red tones | | nature | Earthy greens | | mint | Cool mint/teal |

See all themes in the styl3 docs.

Fills

Fill the empty space below bars or under a line:

const chart = new Chartscii(data, {
  fill: "░",            // any character
  fillColor: "auto",    // or a specific color, gradient, or "auto"
});

Layout

Orientation

Bar charts can be horizontal (default) or vertical:

const chart = new Chartscii(data, {
  orientation: "vertical", // 'horizontal' | 'vertical'
});

Bar alignment

Horizontal alignment

const chart = new Chartscii(data, {
  width: 80,
  padding: 1,
  alignBars: "center",   // 'top' | 'center' | 'bottom' | 'justify'
  color: "auto",
  theme: "beach",
});

| top | bottom | center | justify | |---|---|---|---| | | | | |

Vertical alignment

const chart = new Chartscii(data, {
  orientation: "vertical",
  width: 80,
  padding: 1,
  alignBars: "justify",  // 'left' | 'center' | 'right' | 'justify'
  color: "auto",
  theme: "beach",
});

| left | right | center | justify | |---|---|---|---| | | | | |

Title

Titles support text, alignment, padding, and color (including gradient):

const chart = new Chartscii(data, {
  orientation: "vertical",
  title: {
    text: "Aligned",
    align: "right",                 // 'center' | 'left' | 'right'
    padding: [2, 0],                // CSS-style: [topBottom, leftRight] | [t, r, b, l] | number
    color: "gradient",              // follow chart gradient — or supply your own ('gradient(blue,pink)')
  },
  width: 80,
  color: "gradient(cyan,purple)",
  fill: "▒",
  fillColor: "auto",
  theme: "pastel",
  alignBars: "justify",
});

| left | center | right | |---|---|---| | | | |


Labels

Value labels

Show values on the bars — including segment values for stacked bars:

const chart = new Chartscii(data, {
  valueLabels: true,
  valueLabelsFloatingPoint: 2,    // optional decimal precision
});

Custom formatters

Full control over labels and value labels with custom format functions:

const data = Array.from({ length: 10 }, (_, i) => i + 1);

const chart = new Chartscii(data, {
  fill: "░",
  labelFormat: (label) => `\x1b[7mlabel ${label}`,
  fillColor: "auto",
  padding: 1,
  theme: "beach",
  valueLabels: true,
  orientation: "vertical",
  color: "gradient(lime,purple)",
});

Rich text labels

Use styl3 decorators directly inside labels — *bold*, %italic%, !underline!, @invert@:

const data = [
  { value: 10, label: "*bold* Sales", color: "green" },
  { value: 5, label: "%italic% Returns", color: "red" },
  { value: 8, label: "!underline! Pending", color: "yellow" },
  { value: 3, label: "@invert@ Cancelled", color: "purple" },
];

const chart = new Chartscii(data, {
  barSize: 16,
  theme: "pastel",
  alignBars: "justify",
  orientation: "vertical",
  stackColors: ["red", "orange", "yellow"],
});

Stacked bars

Visualize multi-dimensional data with stacked segments. Works in both orientations.

Vertical

const data: InputData[] = [
  { label: "Mon", value: [5, 10, 5] },
  { label: "Tue", value: [7, 3, 10] },
  { label: "Wed", value: [10, 6, 4] },
  { label: "Thu", value: [3, 6, 11] },
  { label: "Fri", value: [8, 6, 6] },
  { label: "Sat", value: [11, 5, 6] },
  { label: "Sun", value: [9, 6, 5] },
];

const chart = new Chartscii(data, {
  height: 10,
  width: 50,
  padding: 5,
  theme: "pastel",
  orientation: "vertical",
  alignBars: "justify",
  stackColors: ["red", "orange", "yellow"],
});

Horizontal

const chart = new Chartscii(data, {
  barSize: 2,
  width: 60,
  padding: 1,
  theme: "pastel",
  alignBars: "justify",
  colorLabels: true,
  color: "green",
  stackColors: ["green", "pink", "blue"],
});

Stacked value-label formatting

valueLabelFormat receives an array of segment labels, so you can format them however you like:

const data: InputData[] = [
  { label: "Jan", value: [2, 8] },
  { label: "Feb", value: [1, 9] },
  { label: "Mar", value: [3, 7] },
  { label: "Apr", value: [6, 4] },
  { label: "May", value: [3, 7] },
  { label: "Jun", value: [9, 1] },
  { label: "Jul", value: [4, 6] },
];

const chart = new Chartscii(data, {
  barSize: 2,
  width: 60,
  padding: 2,
  alignBars: "justify",
  color: "gradient(#72cac6,#CA7276)",
  valueLabels: true,
  valueLabelFormat: (values) => values.map((v) => Number(v) / 10).join(" / "),
  stackColors: ["#72cac6", "#CA7276"],
});

Auto-colored stacks

Stacked charts also support color: "auto" for palette cycling per segment:

…and partial overrides — set color on a specific data point to override that point's segments:

const data: InputData[] = [
  // ...
  { label: "Thu", value: [3, 6, 11], color: ["cyan", "pink", "purple"] },
  // ...
];

Animation

Create smooth terminal animations with built-in easings:

const data = Array.from({ length: 20 }, (_, i) => ({
  value: Math.round(Math.sin(i / 3) * 10 + 15),
  label: `${i}`,
}));

const chart = new Chartscii(data, {
  width: 60,
  title: {
    text: "Gradient Aligned Center",
    align: "center",
    color: "gradient",
  },
  orientation: "vertical",
  color: "gradient(pink,cyan)",
  theme: "beach",
  fill: "░",
  padding: 1,
  fillColor: "auto",
  valueLabelsFloatingPoint: 0,
  valueLabels: true,
});

chart.animate({ duration: 1500, easing: "easeInOut", fps: 60 });

Manual frames

Drive your own loop and re-render in place using \x1B[H to reset the cursor:

const frames = 120;
for (let frame = 0; frame < frames; frame++) {
  const data = Array.from({ length: 40 }, (_, i) => {
    const value = Math.sin((i + frame) / 4) * 10 + 12;
    return { value: Math.round(value), label: "" };
  });

  const chart = new Chartscii(data, {
    orientation: "vertical",
    height: 24,
    naked: true,
    labels: false,
    color: "gradient(cyan,purple,pink:vertical)",
    fill: "░",
    fillColor: "auto",
  });

  process.stdout.write("\x1B[H" + chart.create());
}

Configuration reference

| Option | Type | Default | Description | |---|---|---|---| | type | ChartType | 'bar' | 'bar', 'line', 'step', 'scatter', 'candlestick', 'status' | | width | number | 100 | Chart width in characters | | height | number | 10 | Chart height in lines | | padding | number | 0 | Space between bars / cells | | barSize | number | 1 | Thickness of each bar / candlestick body / status cell | | orientation | string | 'horizontal' | 'horizontal' or 'vertical' (bar charts only) | | alignBars | string | 'justify' | Bar alignment | | title | string \| TitleConfig | '' | Chart title | | char | string | '█' | Character used for bars | | fill | string | — | Fill character for empty space (line/step area fill on bar charts) | | fillColor | string | — | Fill color or 'auto' | | color | see Color forms | — | Bar color, gradient, 'auto', per-series array, [bull, bear], or status map | | theme | string | '' | Theme name from styl3 | | naked | boolean | false | Hide structure characters | | labels | boolean | true | Show bar / x-axis / cell labels | | colorLabels | boolean | true | Color the labels | | valueLabels | boolean | false | Show values on bars (segment values for stacked) | | valueLabelsFloatingPoint | number | — | Decimal precision | | labelFormat | function | — | Custom label formatter | | valueLabelFormat | (values: string[]) => string | — | Custom value-label formatter | | percentage | boolean | false | Show percentages | | sort | boolean | false | Sort ascending | | reverse | boolean | false | Reverse order | | scale | string \| number | 'auto' | 'auto', 'relative', 'relative-zero', or number | | stackColors | string[] | — | Stacked segment colors | | stackLabels | string[] | — | Stacked segment labels | | richLabels | boolean | true | Enable styl3 rich text decorators in labels | | structure | object | — | Custom border characters | | variant | 'sharp' \| 'smooth' | 'sharp' | step corner style; line ignores | | points | boolean | false | Draw a marker at each data point on line / step | | pointChar | string | '●' | Marker character (also scatter's default) | | legend | boolean \| LegendConfig | false | Show a legend on multi-series line / step / scatter, on candlestick, status |

// Any chart — single color, gradient, or auto palette
color: "green"
color: "gradient(pink,cyan)"
color: "auto"

// Multi-series line / step / scatter — one entry per series
color: ["gradient(pink,cyan)", "gradient(orange,yellow)", "red"]

// Candlestick — [bullish, bearish]
color: ["green", "red"]

// Status — map of status key → color
color: { 0: "red", 1: "green", 2: "yellow", 3: "#888" }
color: { ok: "green", warning: "yellow", error: "red" }
legend: {
  enabled?: boolean;                           // default: true when `legend` is provided
  values?: string[];                           // labels per series; defaults to "Series #1", "Series #2", …
  position?: 'top' | 'bottom';                 // default: 'top'
  align?: 'left' | 'center' | 'right';         // default: 'left'
}

legend: true uses defaults. Single-series line/step/scatter ignore the legend (no legend would be useful with one entry). For status, values labels the status keys in legend order.

| Mode | Behavior | |---|---| | 'auto' | Absolute scaling from 0 to max | | 'relative' | Maps [min, max][1, size] — emphasizes differences | | 'relative-zero' | Maps [min, max][0, size] — max contrast | | number | Fixed scale factor: value / scale |

structure: {
  x: '═',           // horizontal axis
  y: '╢',           // tick mark
  axis: '║',        // vertical axis
  topLeft: '╔',     // top-left corner
  bottomLeft: '╚',  // bottom-left corner
}

API

import Chartscii from "chartscii";

const chart = new Chartscii(data: InputData[] | InputData[][], options?: ChartOptions);

chart.create();   // returns the chart as a string
chart.animate({ duration, fps, easing, step, frames });
type InputData =
  | number
  | {
      // bar / line / step / scatter:        number
      // stacked bar:                        number[]  or  { value: number; color?: string }[]
      // candlestick:                        [open, high, low, close]  (number[])
      // status (grid mode):                 number | string  (status key)
      // status (row mode):                  number[] | string[]  (one cell per entry)
      value: number | number[] | string | { value: number; color?: string }[];
      label?: string;
      color?: string | string[];
    };

CLI

There's an officially supported chartscii CLI: chartscii-cli.


Contributing

Contributions are welcome! Please open an issue or submit a pull request.


License

MIT © tool3