Show HN: ChartGPU – WebGPU-powered charting library (1M points at 60fps) (github.com)

670 points by huntergemmer ↗ HN
Creator here. I built ChartGPU because I kept hitting the same wall: charting libraries that claim to be "fast" but choke past 100K data points.

The core insight: Canvas2D is fundamentally CPU-bound. Even WebGL chart libraries still do most computation on the CPU. So I moved everything to the GPU via WebGPU:

- LTTB downsampling runs as a compute shader - Hit-testing for tooltips/hover is GPU-accelerated - Rendering uses instanced draws (one draw call per series)

The result: 1M points at 60fps with smooth zoom/pan.

Live demo: https://chartgpu.github.io/ChartGPU/examples/million-points/

Currently supports line, area, bar, scatter, pie, and candlestick charts. MIT licensed, available on npm: `npm install chartgpu`

Happy to answer questions about WebGPU internals or architecture decisions.

92 comments

[ 3.4 ms ] story [ 85.0 ms ] thread
(comment deleted)
Wa, this is smooth, man. This is so cool. This is really sexy and cool, the examples page (https://chartgpu.github.io/ChartGPU/examples/index.html) has many good.

I hope you have a way to monetize/productize this, because this has three.js potential. I love this. Keep goin! And make it safe (a way to fund, don't overextend via OSS). Good luck, bud.

Also, you are a master of naming. ChartGPU is a great name, lol!

This looks great. Quick feedback, scrollbars don't work well on my mac mini M1. The bar seems to move twice as fast as the mouse.
No Firefox support? It has had WebGPU support since version 141.

Even when I turn on dom.webgpu.enabled, I still get "WebGPU is disabled by blocklist" even though your domain is not in the blocklist, and even if I turn on gfx.webgpu.ignore-blocklist.

Amazing. I can't express how thankful I am for you building this.
Fun benchmark :) I'm getting 165 fps (screen refresh rate), 4.5-5.0 in GPU time and 1.0 - 1.2 in CPU time on a 9970x + RTX Pro 6000. Definitely the smoothest graph viewer I've used in a browser with that amount of data, nicely done!

Would be great if you had a button there one can press, and it does a 10-15 second benchmark then print a min/max report, maybe could even include loading/unloading the data in there too, so we get some ranges that are easier to share, and can compare easier between machines :)

Doesn't work on my Android phone because no GPU (but I have webgl is that not enough?)
Cool to see that this project started 5 days ago! Unfortunately, I can not make it work on my system (Ubuntu, chrome, WebGPU enabled as described in the documentation). On the other hand, It works on my Android phone...

Funny enough, I am doing something very similar: a C++ portable (Windows, Linux MacOS) charting library, that also compile to WASM and runs in the browser...

I am still at day 2, so see you in 3 days, I guess!

When did WebGPU become good enough at compute shaders? When I tried and failed at digging through the spec about a year ago it was very touch and go.

Maybe am just bad at reading specifications or finding the right web browser.

(comment deleted)
Both a .cursor AND a .claude folder, what a yikes. Slop post galore
Fantasic Hunter, congrats!

I've been looking for a followup to uPlot - Lee who made uPlot is a genius and that tool is so powerful, however I need OffscreenCanvas running charts 100% in worker threads. Can ChartGPU support this?

I started Opus 4.5 rewrite of uPlot to decouple it from DOM reliance, but your project is another level of genius.

I hope there is consideration for running your library 100% in a worker thread ( the data munging pre-chart is very heavy in our case )

Again, congrats!

Nicely done. Will you be able to render 3D donuts? And even animations, say pick a slice & see it tear apart from the donut.
I've always been a bit skeptical of JS charting libs that want to bring the entire data to the client and do the rendering there, vs at least having the option to render image tiles on the server and then stream back tooltips and other interactive elements interactively.

However, this is pretty great; there really aren't that many use cases that require more than a million points. You might finally unseat dygraphs as the gold standard in this space.

The API and ABI for this are tricky to get right.
The number of points actually being rendered doesn't seem to warrant the webgpu implementation. It's similar to the number of points that cubism.js could throw on the screen 15 years ago.
I just rewrote all the graphs on phrasing [1] to webgl. Mostly because I wanted custom graphs that didn’t look like graphs, but also because I wanted to be able to animate several tens of thousands of metrics at a time.

After the initial setup and learning curve, it was actually very easy. All in all, way less complicated than all the performance hacks I had to do to get 0.01% of the data to render half as smooth using d3.

Although this looks next level. I make sure all the computation happens in a single o(n) loop but the main loop still takes place on the cpu. Very well done

To anyone on the fence, GPU charting seemed crazy to me beforehand (classic overengineering) but it ends up being much simpler (and much much much smoother) than traditional charts!

[1] https://phrasing.app

Very cool. Shame there's not a webgl fallback though. It will be a couple of years until webgpu adoption is good enough.

https://caniuse.com/webgpu

+1

Please support a fallback, ideally a 2D one too. WebGPU and WebGL are a privacy nightmare and the former is also highly experimental. I don't mind sub-60 FPS rendering, but I'd hate having to enable either of them just to see charts if websites were to adopt this library.

The web is already bad requiring JavaScript to merely render text and images. Let's not make it any worse.

WebGL punts to WebGPU for decent compute shaders.
(comment deleted)
WebGPU is a security nightmare.

The idea that GPU vendors are going to care about memory access violations over raw performance is absurd.

Very Nice. There is an issue with panning on the million point demo -- it currently does not redraw until the dragging velocity is below some threshold, but it should seem like the points are just panned into frame. It is probably enough to just get rid of the dragging velocity threshold, but sometimes helps to cache an entire frame around the visible range
Right on time.

We’ve been working on a browser-based Link Graph (osint) analysis tool for months now (https://webvetted.com/workbench). The graph charting tools on the market are pretty basic for the kind of charting we are looking to do (think 1000s of connected/disconnected nodes/edges. Being able to handle 1M points is a dream.

This will come in very handy.

You may enjoy Graphistry (eg, pygraphistry, GraphistryJS), where our users regularly do 1M+ graph elements interactively, such as for event & entity data. Webgl frontend, GPU server backend for layouts too intense for frontend. We have been working on stability over the last year with large-scale rollout users (esp cyber, IT, social, finance, and supply chain), and now working on the next 10X+ of visual scaling. Python version: https://github.com/graphistry/pygraphistry . It includes many of the various tricks mentioned here, like GPU hitmapping, and we helped build various popular libs like apache arrow for making this work end-to-end :)

Most recently adding to the family is our open source GFQL graph language & engine layer (cypher on GPUs, including various dataframe & binary format support for fast & easy large data loading), and under the louie.ai umbrella, piloting genAI extensions

Is this an open source Palantir?
this is so well done, thanks for sharing it. i've been trying to communicate with people how we are living in the golden age of dev where things that previously couldn't have been created, now can be. this is an amazing example of that.