Billboard.js: D3-Powered Charts That Hit Number One
If you have ever tried to build a chart with raw D3.js, you know the drill: selections, enters, exits, transitions, scales, axes, and about two hundred lines of code before a single bar appears on screen. Billboard.js exists to short-circuit that entire process. Built on top of D3.js by the engineering team at NAVER (Korea's largest tech company), it gives you a declarative configuration object in and a fully interactive SVG chart out. Line charts, bar charts, pie charts, candlesticks, radar plots, treemaps, funnels -- the whole catalog is covered. And yes, there is an official React wrapper.
The Full Setlist
The feature list for billboard.js reads like a greatest hits album:
- Over 20 chart types including line, spline, step, area, bar, scatter, bubble, pie, donut, gauge, radar, treemap, candlestick, funnel, and polar
- SVG-based rendering for crisp output at any resolution, easy CSS styling, and accessibility-friendly markup
- Five built-in themes: datalab, dark, insight, graph, and modern
- Full TypeScript support with shipped type definitions
- Official React component via
@billboard.js/react - Packaged builds that bundle D3.js so you do not have to manage it separately
- Server-side image generation for Node.js environments
- Smooth transitions and animations out of the box
- Active maintenance with frequent releases (three releases in January 2026 alone)
Getting It on Stage
Installation is straightforward. You can pull in the library alongside its D3 dependencies, or use the packaged build that includes everything.
npm install billboard.js
yarn add billboard.js
If you are working in React, grab the official wrapper too:
npm install @billboard.js/react billboard.js
You will also need to import a CSS theme. Billboard.js ships five of them, and you pick whichever suits your project.
Your First Number One Hit
Spinning Up a Line Chart
The core API revolves around a single function: bb.generate(). You pass it a configuration object describing your data, chart type, and target DOM element. Here is the simplest possible line chart:
import bb, { line } from "billboard.js";
import "billboard.js/dist/billboard.css";
bb.generate({
bindto: "#chart",
data: {
columns: [
["Revenue", 30, 200, 100, 400, 150, 250],
["Expenses", 50, 20, 10, 40, 15, 25],
],
type: line(),
},
});
That is it. Two data series, rendered as interactive lines with hover tooltips, a legend, and animated transitions. The columns format uses the first element of each array as the series name and the rest as data points.
Switching to Bars and Donuts
Changing chart types is as simple as swapping the type function. No structural changes to your code:
import bb, { bar, donut } from "billboard.js";
import "billboard.js/dist/theme/modern.css";
// A grouped bar chart
bb.generate({
bindto: "#sales-chart",
data: {
columns: [
["Q1", 120, 80, 95],
["Q2", 140, 110, 130],
["Q3", 90, 70, 85],
],
type: bar(),
},
bar: {
width: { ratio: 0.6 },
},
axis: {
x: {
type: "category",
categories: ["Product A", "Product B", "Product C"],
},
},
});
// A donut chart
bb.generate({
bindto: "#market-share",
data: {
columns: [
["Chrome", 65],
["Safari", 19],
["Firefox", 8],
["Edge", 5],
["Other", 3],
],
type: donut(),
},
donut: {
title: "Browser Share",
},
});
Plugging Into React
The official @billboard.js/react wrapper makes integration with React components seamless:
import React from "react";
import BillboardChart from "@billboard.js/react";
import { line } from "billboard.js";
import "billboard.js/dist/billboard.css";
const SalesChart: React.FC = () => {
const options = {
data: {
columns: [
["Monthly Sales", 340, 520, 480, 610, 590, 720],
["Target", 400, 400, 400, 500, 500, 500],
],
type: line(),
},
axis: {
x: {
type: "category",
categories: ["Jan", "Feb", "Mar", "Apr", "May", "Jun"],
},
},
};
return <BillboardChart bb={options} />;
};
export default SalesChart;
The component handles mounting, updating, and cleanup automatically. Pass new options and the chart re-renders with smooth transitions.
Turning It Up to Eleven
Themed to Perfection
Billboard.js ships five CSS themes you can swap by changing a single import. No configuration changes needed -- the chart structure stays identical:
// Pick your vibe
import "billboard.js/dist/theme/dark.css";
// or: billboard.css (default), datalab.css, insight.css, graph.css, modern.css
The dark theme is particularly useful for dashboards with dark backgrounds. Each theme adjusts colors, fonts, grid lines, and tooltip styles in one shot.
Real-Time Data Updates
Charts created with bb.generate() return a chart instance you can manipulate after creation. This is where things get powerful for live dashboards:
import bb, { line } from "billboard.js";
const chart = bb.generate({
bindto: "#live-metrics",
data: {
columns: [["CPU", 45, 52, 48, 55, 60]],
type: line(),
},
axis: {
y: {
max: 100,
min: 0,
label: "Usage %",
},
},
});
// Push new data every second
setInterval(() => {
const newValue = Math.floor(Math.random() * 40) + 30;
chart.flow({
columns: [["CPU", newValue]],
length: 0,
});
}, 1000);
The flow() method appends data with a smooth sliding animation. You can also use load() to replace data entirely or unload() to remove series on the fly.
Candlestick Charts for Financial Data
Added in v3.0, candlestick charts bring financial visualization capabilities without needing a separate library:
import bb, { candlestick } from "billboard.js";
bb.generate({
bindto: "#stock-chart",
data: {
columns: [
[
"Stock Price",
{ open: 100, high: 130, low: 95, close: 120 },
{ open: 120, high: 145, low: 115, close: 135 },
{ open: 135, high: 150, low: 110, close: 115 },
{ open: 115, high: 140, low: 105, close: 138 },
{ open: 138, high: 155, low: 130, close: 148 },
],
],
type: candlestick(),
},
candlestick: {
color: {
down: "#e74c3c",
up: "#2ecc71",
},
},
axis: {
x: {
type: "category",
categories: ["Mon", "Tue", "Wed", "Thu", "Fri"],
},
},
});
Each data point takes an object with open, high, low, and close values. The library handles the wick-and-body rendering, color coding for up and down movements, and tooltip formatting automatically.
Arc Annotations on Pie and Donut Charts
The latest v3.18.0 release introduced arc annotations, letting you overlay labels and markers directly onto pie and donut segments:
import bb, { pie } from "billboard.js";
bb.generate({
bindto: "#annotated-pie",
data: {
columns: [
["Infrastructure", 42],
["Salaries", 35],
["Marketing", 15],
["R&D", 8],
],
type: pie(),
},
arc: {
needle: {
show: true,
value: 60,
},
},
});
This is particularly useful for gauge-style visualizations where you need to indicate thresholds or targets on circular charts.
The Encore
Billboard.js occupies a sweet spot in the charting library landscape. It offers substantially more power and customization than simpler canvas-based alternatives like Chart.js, while demanding far less boilerplate than working with raw D3.js. The SVG rendering means your charts look sharp on retina displays, print cleanly, and play nicely with CSS. The built-in themes save you from the "ugly default chart" problem that plagues many visualization libraries. And with an official React wrapper, TypeScript definitions, and active maintenance backed by NAVER, it is a solid bet for production applications that need serious data visualization without a serious learning curve.