[{"data":1,"prerenderedAt":469},["ShallowReactive",2],{"musings-chart-libraries":3},{"id":4,"title":5,"body":6,"date":458,"description":459,"extension":460,"image":461,"meta":462,"navigation":463,"path":464,"seo":465,"stem":466,"summary":467,"__hash__":468},"musings/musings/chart-libraries.md","JS Chart Libraries",{"type":7,"value":8,"toc":431},"minimark",[9,14,19,23,27,32,43,46,54,57,65,73,77,80,83,91,94,101,105,118,121,124,131,135,138,141,148,151,154,157,164,168,171,175,178,198,202,220,224,233,236,254,258,276,280,306,310,313,336,340,358,362,366,398,402,405],[10,11,13],"h1",{"id":12},"chart-libraries","Chart Libraries",[15,16,18],"h2",{"id":17},"why-plot-with-javascript","Why plot with javascript?",[20,21,22],"p",{},"How else can you do it? Javascript and HTML is what is being used under the hood by most Python and R chart libraries as well.\nThere is no simpler, more controllable and more powerful way to make charts than with javascript.\nJavascript runs where the data is consumed: the browser. Plotting there means charts can be interactive, responsive, and streamed without a render server. Think also tooltips, cross-filters, and anything can be dynamic.",[15,24,26],{"id":25},"the-historical-foundation","The historical foundation",[28,29,31],"h3",{"id":30},"d3js","D3.js",[20,33,34,35,42],{},"We owe a lot to this library. It was created by ",[36,37,41],"a",{"href":38,"rel":39},"https://bost.ocks.org/mike/",[40],"nofollow","Mike Bostock"," while he was a visualization journalist at the New York Times, building on earlier work from the Stanford Vis Group.",[20,44,45],{},"D3 is not a chart library — it's a set of abstractions over the DOM that let developers bind data to SVG (or any DOM node), giving immense flexibility for design, animation, and interaction. Nearly every modern charting library in JS either uses D3 under the hood or borrows its ideas (scales, selections, data joins).",[20,47,48,49,53],{},"It's very simple and fun to learn. This is about putting boxes, circles, points, traces and anything on ",[50,51,52],"code",{},"\u003Cdiv>"," and you can control exactly what should happen based on data ingested. For every row and every cell, individually.",[20,55,56],{},"It gets more complex how to combine all the elements to make good looking charts.",[20,58,59,60],{},"Repo: ",[36,61,64],{"href":62,"rel":63},"https://github.com/d3/d3",[40],"d3/d3",[20,66,67,68,72],{},"Its spiritual successor, from the same author, is ",[69,70,71],"strong",{},"Observable Plot"," — see below.",[15,74,76],{"id":75},"the-modern-trio","The modern trio",[20,78,79],{},"These three libraries cover, in my opinion, the majority of serious charting needs today. Pick based on the axis that matters most: ergonomics, grammar, or production polish.",[28,81,71],{"id":82},"observable-plot",[20,84,85,86,90],{},"Plot is Mike Bostock's successor to D3 for the \"just make a chart\" case. Instead of wiring up scales and axes by hand, you describe ",[87,88,89],"em",{},"marks"," (dot, line, bar, rect…) over data and Plot figures out the rest. It keeps D3's flexibility when you need to drop down, but removes the boilerplate for the 90% case.",[20,92,93],{},"Best for: exploratory analysis, notebooks, fast iteration, charts that will later be customized.",[20,95,59,96],{},[36,97,100],{"href":98,"rel":99},"https://github.com/observablehq/plot",[40],"observablehq/plot",[28,102,104],{"id":103},"vega-lite","Vega-Lite",[20,106,107,108,111,112,117],{},"Vega-Lite is a high-level ",[87,109,110],{},"grammar of interactive graphics",", developed at the ",[36,113,116],{"href":114,"rel":115},"https://idl.cs.washington.edu/",[40],"UW Interactive Data Lab",". You write a JSON spec describing the data, encoding, and marks, and Vega-Lite compiles it to a full Vega spec, which in turn renders via Canvas or SVG.",[20,119,120],{},"The grammar is the selling point: specs are portable, composable, and language-agnostic (Altair in Python, VegaFusion, etc.). Interactions — brushing, linking, filtering — are first-class citizens of the spec rather than imperative code.",[20,122,123],{},"Best for: reproducible analysis, multi-language pipelines, rich interactive exploration, embedding in tools like Jupyter or Observable.",[20,125,59,126],{},[36,127,130],{"href":128,"rel":129},"https://github.com/vega/vega-lite",[40],"vega/vega-lite",[28,132,134],{"id":133},"apache-echarts","Apache ECharts",[20,136,137],{},"ECharts is the most powerful of the three and is my go-to by default. Originally developed at Baidu and now an Apache Software Foundation project, it ships with a vast catalog of chart types out of the box — including ones the other two don't really handle: sankey, treemap, graph/network, gauges, geo maps, candlesticks, parallel coordinates, 3D via GL, etc.",[20,139,140],{},"It renders to Canvas (or SVG), handles very large datasets well, has excellent built-in interactivity (zoom, brush, tooltip, dataZoom), and its theming system is mature. Even has WebGL support.",[20,142,143,144,147],{},"Canvas is a big deal... Instead of handling many DOM elements through SVG, it actually \"draws\" in one ",[50,145,146],{},"\u003Ccanvas>"," element so this makes it a lot more performant for heavy charts.",[20,149,150],{},"It can also do the heavy work in web workers, thereby freeing the main thread so the user does not feel any impact on the website.",[20,152,153],{},"It also has a very handy function to get the image from the chart, so you can pass that to any vision LLM to analyze.",[20,155,156],{},"Best for: dashboards, business apps, large datasets, when you need unusual chart types without pulling in a second library.",[20,158,59,159],{},[36,160,163],{"href":161,"rel":162},"https://github.com/apache/echarts",[40],"apache/echarts",[15,165,167],{"id":166},"other-libraries-worth-knowing","Other libraries worth knowing",[20,169,170],{},"A non-exhaustive list of other libraries you'll encounter:",[28,172,174],{"id":173},"webgl","WebGL",[20,176,177],{},"WebGL allows you to draw A LOT of data points. When building visualizations with e.g. D3 there is a limit to how many elements can be displayed and controlled. WebGL uses the computer's GPU to render large amounts of data points effectively.",[179,180,181,190],"ul",{},[182,183,184,189],"li",{},[36,185,188],{"href":186,"rel":187},"https://echarts.apache.org/en/option-gl.html",[40],"ECharts"," has its own WebGL interface. Check the cool demos",[182,191,192,197],{},[36,193,196],{"href":194,"rel":195},"https://github.com/visgl/deck.gl",[40],"Deck.gl"," is very cool",[28,199,201],{"id":200},"time-series","Time Series",[179,203,204,212],{},[182,205,206,211],{},[36,207,210],{"href":208,"rel":209},"https://github.com/leeoniya/uPlot",[40],"uPlot"," is a small and fast time series charting library",[182,213,214,219],{},[36,215,218],{"href":216,"rel":217},"https://github.com/metricsgraphics/metrics-graphics",[40],"MetricsGraphics"," should really go into the \"Old\" section but I loved this library when it came out around 2014. Very simple and very smooth, just lines and bars.",[28,221,223],{"id":222},"d3-wrappers","D3 Wrappers",[20,225,226,227,232],{},"Most chart libraries are built on top of D3, abstracting away standard charts like bars, lines etc...\nIn the age of AI, as of 2026 (less so in 2025), D3 can be written effectively by coding agents. So not only are these wrappers less relevant, but skipping the expertise needed to control D3 charts forgoes amazing and creative possibilities to go beyond standard chart forms. Just look at the amazing ",[36,228,231],{"href":229,"rel":230},"https://observablehq.com/@d3/gallery",[40],"D3 demos",".",[20,234,235],{},"But they can still save a few prompts.",[179,237,238,246],{},[182,239,240,245],{},[36,241,244],{"href":242,"rel":243},"https://github.com/airbnb/visx",[40],"visx"," is a D3 wrapper from AirBNB. Offers a large variety of cool charts. It's a high quality library.",[182,247,248,253],{},[36,249,252],{"href":250,"rel":251},"https://github.com/chartjs/Chart.js",[40],"Chart.js"," for some reason I see being used a lot. It's ok good but I'm not sure why it's so popular.",[28,255,257],{"id":256},"react-wrappers","React Wrappers",[179,259,260,268],{},[182,261,262,267],{},[36,263,266],{"href":264,"rel":265},"https://github.com/recharts/recharts",[40],"Recharts"," is nice simple to use React-based charts, cool for server-side rendering.",[182,269,270,275],{},[36,271,274],{"href":272,"rel":273},"https://github.com/FormidableLabs/victory",[40],"Victory"," I never tried this one but could not make a section with one item.",[28,277,279],{"id":278},"old","Old",[179,281,282,290,298],{},[182,283,284,289],{},[36,285,288],{"href":286,"rel":287},"https://github.com/chartist-js/chartist",[40],"Chartist"," is a simple basic old chart library, limited, author is a nice guy though",[182,291,292,297],{},[36,293,296],{"href":294,"rel":295},"https://github.com/c3js/c3",[40],"C3.js"," a simple D3 wrapper, was cool 10 years ago",[182,299,300,305],{},[36,301,304],{"href":302,"rel":303},"https://github.com/frappe/charts",[40],"Frappe Charts"," last commit 2 years ago...",[28,307,309],{"id":308},"licensed","Licensed",[20,311,312],{},"Some companies' business model is to maintain chart libraries.\nThese libraries are high quality chart APIs and companies can shell out a few hundred bucks for legal serenity.\nNot for me but listing nevertheless.",[179,314,315,322,329],{},[182,316,317],{},[36,318,321],{"href":319,"rel":320},"https://github.com/highcharts/highcharts",[40],"Highcharts",[182,323,324],{},[36,325,328],{"href":326,"rel":327},"https://github.com/apexcharts/apexcharts.js",[40],"ApexCharts",[182,330,331],{},[36,332,335],{"href":333,"rel":334},"https://github.com/amcharts/amcharts5",[40],"amCharts",[28,337,339],{"id":338},"avoid","Avoid",[179,341,342,350],{},[182,343,344,349],{},[36,345,348],{"href":346,"rel":347},"https://developers.google.com/chart",[40],"Google Charts"," is very limited, outdated, weird setup linked to Google infra. Absolutely avoid.",[182,351,352,357],{},[36,353,356],{"href":354,"rel":355},"https://github.com/plotly/plotly.js",[40],"Plotly.js"," has existed for a long time and is used everywhere, particularly in Python and R. Very unfairly and subjectively: I don't like it. I feel it's overrated. It used to be a service for building and sharing charts and wasn't really in the open source game.",[15,359,361],{"id":360},"other-visualization-tools","Other visualization tools",[28,363,365],{"id":364},"grids","Grids",[179,367,368,376,384],{},[182,369,370,375],{},[36,371,374],{"href":372,"rel":373},"https://github.com/ag-grid/ag-grid",[40],"AG Grid"," is the best-in-class data grid today. Fast, feature-complete (virtualization, grouping, pivoting, filtering, editing), with both community and enterprise editions. If you need a grid that won't embarrass you in front of users, start here.",[182,377,378,383],{},[36,379,382],{"href":380,"rel":381},"https://github.com/handsontable/handsontable",[40],"Handsontable"," used to be the default pick, but has grown restrictive and quirky over the years (licensing, API weirdness). Still extremely capable and best-in-class, but hard to recommend as a first choice now.",[182,385,386,391,392,397],{},[36,387,390],{"href":388,"rel":389},"https://github.com/TanStack/virtual",[40],"TanStack Virtual"," is not a grid but a virtualization primitive. The roll-your-sleeves option: pair it with your own rendering and you can build exactly the grid you want, at the cost of writing it yourself. Pairs well with ",[36,393,396],{"href":394,"rel":395},"https://github.com/TanStack/table",[40],"TanStack Table"," for the headless logic.",[28,399,401],{"id":400},"spreadsheets","Spreadsheets",[20,403,404],{},"When you need cells with formulas, not just rows with data:",[179,406,407,415,423],{},[182,408,409,414],{},[36,410,413],{"href":411,"rel":412},"https://github.com/ironcalc/IronCalc",[40],"IronCalc"," is a Rust-based spreadsheet engine compiled to WASM, with a clean JS API and a full formula engine. Modern, fast, embeddable, and open source. You still need a visual layer for it, which you can also get from the beautiful main example. It's very promising and the author seems very genuine about the craft and the goal to make the best engine.",[182,416,417,422],{},[36,418,421],{"href":419,"rel":420},"https://github.com/dream-num/univer",[40],"Univer"," seems very good but I have not tried it.",[182,424,425,430],{},[36,426,429],{"href":427,"rel":428},"https://github.com/jspreadsheet/ce",[40],"jSpreadsheet"," is the community edition of an expensive TypeScript spreadsheet product.",{"title":432,"searchDepth":433,"depth":433,"links":434},"",2,[435,436,440,445,454],{"id":17,"depth":433,"text":18},{"id":25,"depth":433,"text":26,"children":437},[438],{"id":30,"depth":439,"text":31},3,{"id":75,"depth":433,"text":76,"children":441},[442,443,444],{"id":82,"depth":439,"text":71},{"id":103,"depth":439,"text":104},{"id":133,"depth":439,"text":134},{"id":166,"depth":433,"text":167,"children":446},[447,448,449,450,451,452,453],{"id":173,"depth":439,"text":174},{"id":200,"depth":439,"text":201},{"id":222,"depth":439,"text":223},{"id":256,"depth":439,"text":257},{"id":278,"depth":439,"text":279},{"id":308,"depth":439,"text":309},{"id":338,"depth":439,"text":339},{"id":360,"depth":433,"text":361,"children":455},[456,457],{"id":364,"depth":439,"text":365},{"id":400,"depth":439,"text":401},"2026-04-14T00:00:00.000Z","an overview of javascript chart libraries","md","/images/chart-libraries.jpg",{},true,"/musings/chart-libraries",{"title":5,"description":459},"musings/chart-libraries","Javascript is the simplest, most controllable and more powerful way to make charts. Some tablestake libraries lead the way. But an extensive list of libraries exist.","UVsexchnA2-WYd6aI5GravBhmpeMeSkKCMWc0CULpK0",1777240264052]