I've been working with data visualizations for a long time, almost a decade, and most of that time my main tool was D3.js. But recently I got to work with Chart.js as well, building a large reporting dashboard project from scratch. This experience made me think about how different dataviz libraries can be — in patterns, approaches, and even in what they are designed for.
That, in turn, made me curious about the wider view on them, so I decided to do a bit of digging. In the end I put together eight popular JavaScript libraries that represent very different ways of building charts.
D3.js
Type: low-level toolkit
D3 is a set of tools for working with data and DOM/SVG elements. It lets you build almost anything, but you have to assemble most of it yourself, like a complex construction set.
I love D3 and it’s still the library I use most often. The learning curve is steep, but in return you get almost unlimited flexibility. At some point it started to feel more like craft than just programming.
const line = d3.line()
.x(d => xScale(d.x))
.y(d => yScale(d.y));
Chart.js
Type: ready-to-use charting library
Chart.js is a simple and convenient option for most standard charts. Its setup is very fast: you describe the chart through a config object and get a working result almost immediately.
I really like it for visualizations that do not require heavy customization, although a lot can still be achieved with plugins. Many common charts work almost out of the box, with legends, tooltips, and other elements.
new Chart(ctx, {
type: 'bar',
data: { ... },
options: { ... },
});
Apache ECharts
Type: configuration-based charting library
ECharts is a large and powerful system for interactive charts and dashboards, with many built-in chart types and support for fairly large datasets.
I used it on one corporate project and mostly liked it. It feels somewhat similar to Chart.js at first glance, but much more oriented toward analytics systems, dashboards, and interactive interfaces.
const myChart = echarts.init(chartDom);
myChart.setOption({
xAxis: { ... },
yAxis: { ... },
series: [{ ... }],
});
Plotly.js
Type: high-level declarative library
Plotly.js is similar to Chart.js and ECharts in declarative way to describe the charts, but it feels much closer to scientific and analytical visualization. It comes with statistical charts, 3D plots, and many other less typical chart types.
I have not used it in production myself, but browsing the docs was enough to see how broad the built-in chart options are.
const data = [{ x: [...], y: [...], type: 'bar' }];
Plotly.newPlot('chart', data);
Observable Plot
Type: library for quick charts
Observable Plot is great for fast exploratory work. It has a simple API and builds charts from predefined marks rather than long configuration objects.
I played with it a while ago, when it was in beta and pretty rough. Since then, it seems to have evolved a lot and now looks quite solid.
Plot.plot({
marks: [
Plot.barY(data, { x: 'category', y: 'value' }),
],
});
Vega-Lite
Type: declarative grammar of graphics
Vega-Lite describes charts through a JSON with data, marks, encodings, and transformations. Instead of manually assembling chart parts, you only describe its structure and let the system generate the rest.
I have not used it before, but from the docs and examples it looks like a very strong option for quick visualizations.
{
"$schema": "https://vega.github.io/schema/vega-lite/v6.json",
"data": { ... },
"mark": "bar",
"encoding": {
"x": { ... },
"y": { ... }
}
}
G2
Type: grammar-of-graphics-based charting library
G2 is somewhat similar to Vega-Lite in that it also builds on grammar-of-graphics ideas, but it feels more oriented toward practical production-ready charts.
The API looks clean, and the charts themselves look polished and pretty. It also led me into the much larger AntV ecosystem, which is worth exploring on its own.
const chart = new Chart({ container: 'container' });
chart
.interval()
.data(data)
.encode('x', '...')
.encode('y', '...');
chart.render();
deck.gl
Type: GPU-powered framework
deck.gl is designed for large datasets and declaratively defined layers. It lives in a different corner of the visualization world: with maps, dense point clouds, geospatial layers, and highly interactive scenes.
To me, it is basically the world of those beautiful, colorful map-based visualizations you instantly want to zoom into and play with. Always wanted to try, but never had enough time unfortunately.
new DeckGL({
initialViewState: { ... },
controller: true,
layers: [
new ScatterplotLayer({ data }),
],
});
Final thoughts
What I like about this list is how wide the range of charting tools really is. Some of them are built around ready-to-use standard charts. Some are low-level and offer flexibility and full control. Some are closer to formal visualization specifications. And their use cases vary as well: dashboards, interactive sandboxes, analytics, small demos, etc.
So in many cases, the real question is not “which library is better?” but “what do I want to build?”.
Thank you for reading and happy coding! 💛
Top comments (0)