@coroboros/sparkline
v1.0.6
Published
Lightweight, zero-dependency SVG sparkline generator for Node.js.
Maintainers
Readme
@coroboros/sparkline
Lightweight, zero-dependency SVG sparkline generator for Node.js.
Calculates polyline points from a numeric series and returns a pure SVG string. Tune width, height, stroke, coordinate precision, and accessibility metadata.
Contents
Requirements
- Node.js
>=22LTS. Use fnm for version management — Rust-based, faster than nvm. - Any of the following package managers:
pnpm,npm,yarn,bun.
Install
pnpm add @coroboros/sparklinenpm install @coroboros/sparklineyarn add @coroboros/sparklinebun add @coroboros/sparklineUsage
// ESM (recommended)
import { sparkline } from '@coroboros/sparkline';// CommonJS
const { sparkline } = require('@coroboros/sparkline');import { sparkline, SparklineError } from '@coroboros/sparkline';
const values = [10, 50, 50, 200, 0];
try {
const svg = sparkline(values, {
width: 135,
height: 50,
stroke: '#C9A96E',
strokeWidth: 1.25,
strokeOpacity: 1,
precision: 2,
title: 'Price (24h)',
ariaLabel: 'Price trend over the last 24 hours',
description: 'Hourly close for the last 24 hours.',
});
// svg is a string containing <svg>…<polyline/>…</svg>
} catch (err) {
if (err instanceof SparklineError) {
console.error(err.code, err.message);
}
}API
Types
Style and accessibility options for sparkline. Every field is optional. Invalid style options (width, height, stroke, strokeWidth, strokeOpacity, precision) fall back silently to their defaults.
| Option | Type | Default | Description |
| --- | --- | --- | --- |
| width | number | 135 | SVG width, in pixels. Must be > 0. |
| height | number | 50 | SVG height, in pixels. Must be > 0. |
| stroke | string | #C9A96E | Stroke color — CSS named color, hex (#rgb, #rgba, #rrggbb, #rrggbbaa), or functional notation (rgb(), rgba(), hsl(), oklch(), …). |
| strokeWidth | number | 1.25 | Stroke width, in pixels. Must be >= 0. 0 produces an invisible polyline. |
| strokeOpacity | number | 1 | Stroke opacity, in [0, 1]. |
| precision | integer | 2 | Decimal places kept on every coordinate. Integer in [0, 6]. Lower values produce smaller SVGs. |
| title | string | (optional) | Adds a <title> element and sets role="img" plus aria-label on the root <svg> (when ariaLabel is omitted). |
| ariaLabel | string | (optional) | Explicit aria-label on the root <svg>. Takes precedence over title for the accessible name. |
| description | string | (optional) | Adds a <desc> element for screen-reader long-form context. |
Thrown by sparkline. Inherits from Error. See Errors for the code list.
class SparklineError extends Error {
readonly name: 'SparklineError';
readonly code: SparklineErrorCode;
readonly message: string;
}type SparklineErrorCode = 'MISSING_VALUES' | 'INVALID_VALUES' | 'EMPTY_VALUES';Generate an SVG sparkline from an array of numeric values.
Parameters
| Option | Type | Default | Description |
| --- | --- | --- | --- |
| values | ReadonlyArray<number> | (required) | Finite numbers used to draw the sparkline. Must contain at least one element. |
| options? | SparklineOptions | {} | Style and accessibility overrides. |
Returns — string. The SVG markup including <polyline>.
Throws — SparklineError. Invalid values throw with one of MISSING_VALUES, INVALID_VALUES, EMPTY_VALUES. Invalid style options fall back silently to their defaults.
Notes — See bench/baseline.md for SVG-render timings.
Examples
sparkline([10, 50, 50, 200, 0]);
// → <svg viewBox="0 0 135 50" ...><polyline .../></svg>
sparkline([1, 2, 3, 2, 1], {
width: 200,
height: 60,
strokeWidth: 2,
ariaLabel: 'Trend',
});
// → accessible SVG with role="img" and aria-label="Trend"
try {
sparkline([]);
} catch (err) {
if (err instanceof SparklineError) {
err.code; // 'EMPTY_VALUES'
}
}Accessibility
The polyline is inset by strokeWidth / 2 so stroke caps never clip the viewBox edges.
When none of title, ariaLabel, or description are provided, the SVG is marked aria-hidden="true" — treat it as decorative. Pass any of them to opt into an accessible image: the root gets role="img" plus aria-label (from ariaLabel or title), and <title> / <desc> nest inside the SVG.
Gallery
Rendered examples live in assets/examples.
Errors
| Code | Description |
| --- | --- |
| MISSING_VALUES | The values option is missing. |
| INVALID_VALUES | values is not an array, or contains non-finite numbers. |
| EMPTY_VALUES | values is an empty array. |
Debugging
The library uses Node's built-in util.debuglog. Enable it with:
NODE_DEBUG=sparkline node your-script.jsCompared to alternatives
| Feature | sparkline (shiwano) | node-sparkline | @fnando/sparkline | react-sparklines | @coroboros/sparkline |
| ------------------------------------------------------ | :-------------------: | :--------------: | :-----------------: | :----------------: | :------------------------: |
| Output | ASCII | SVG string | SVG (mutates DOM) | React (JSX → SVG) | SVG string |
| Runs in Node without DOM or React | yes | yes | no | no | yes |
| Zero runtime dependencies | no | yes | yes | no | yes |
| Accessibility (title, aria-label, <desc>) | n/a | no | no | no | yes |
| Tunable coordinate precision | no | no | no (fixed) | no | yes |
| Built-in TypeScript types | no | no | no | no | yes |
| ESM + CJS dual build | no | no | no | no | yes |
The gap is accessibility-aware SVG output rendered in Node. sparkline (shiwano) returns Unicode block characters — fine in a terminal, off-limits in an <img> tag or a generated PDF. @fnando/sparkline mutates a passed <svg> DOM element; react-sparklines renders through a React tree. node-sparkline is the closest peer with an SVG string and zero deps, but ships no ARIA support, no precision control, no types, and CJS only. @coroboros/sparkline fills the rest: opt-in title / aria-label / <desc>, coordinate precision for wire-size control, built-in types, and a dual ESM/CJS build.
Contributing
Bug reports and PRs welcome.
- Open an issue before submitting non-trivial PRs.
- Commits follow Conventional Commits.
- Run
pnpm lint && pnpm typecheck && pnpm testbefore pushing. - Target the
mainbranch.
