9 ms·
Why is D3 so Verbose?
- thrown-0825 1y agoI love D3, but its a library not a language.
- TheHeasman 1y agoAgreed. I fudged quite a lot in my post to make it accessible to the layman. Triee to explain to a UX designer I know that "D3 is a library for JavaScript that..." And I saw their brain switch off live in front of me. Semantics matter more than literals sometimes. *EDIT: Grammar. I was typing on my phone. Soz.
- moron4hire 1y agoD3 is a good example of inventing a language without inventing a syntax for that language. It very much is a DSL implemented in JavaScript.
- thrown-0825 1y agook, I'll buy that, definitely feels like it
- bsimpson 1y agoWhen Francisco Tolmasky launched Objective J, he wrote a really interesting article that still impacts how I think about this stuff more than a decade later. Francisco was working on an in-browser slideshow tool like Google Slides, but in the late 00s. To power it, he invented his own language: Objective-J. It had its own toolchain, in the days when most developers were just writing JavaScript inline or maybe in .js files. Remember, it took React a few years to catch on because it required command line tools to translate JSX to JS. This had the same friction, but years earlier. This was the thesis behind Objective-J: In the late 1900s, C was the foundation of a good language, but it needed another layer of abstraction on top of it to be more ergonomic. The developers at NeXT/Apple built that layer and called it Objective-C. Objective-J saw the same potential in JavaScript, and ported the ergonomics of Objective-C atop it. It basically tried to do for JavaScript what Objective-C had done for C. This was the critical part of the argument: JavaScript (in the era before modules, => functions, and the other current niceties) was the core of a useful language, but it needed a more ergonomic layer on top. Libraries like jQuery were building de-facto DSLs, but calling them libraries. Objective-J was taking conceptual responsibility for being a language on top of JavaScript, instead of being "just" a library. By owning up to being its own language, they could take syntactical liberties that they couldn't under the constraints of being just another JS library.
- esafak 1y agoI feel like D3 ought to be the for-computer substrate for libraries that are actually for humans. I suppose it matters less now in the LLM age.
- lionkor 1y agoIf your LLM is the only one that can reasonably maintain your software, you essentially created a new kind of lock-in, similar to what we already solved with open source a long, long time ago. Once your LLM gets too expensive, goes out of business, and the competitors just don't quite do it the way your favorite LLM does it, you have a problem.
- esafak 1y agoSpeaking for myself, when it comes to D3 the problem is being locked out :)
- deleted 1y ago[deleted]
- lenerdenator 1y agoMore granular control, more verbosity. I am still proud of the D3 gadget I made about 8 years back as a green web dev. Couldn't have made it any other way, not sure if I could with any other library today. Wouldn't want to do it again, though, unless I was a dedicated front-end guy.
- Rendello 1y agoWhat was the gadget? I'm also more of a back-end guy that occasionally does front-end. I have a strong design taste, but it takes a lot of effort to improve my skills be able to act on it. I feel like D3 appeals to people with a strong sense of taste.
- lenerdenator 1y agoIt was a little gauge to help visualize how much money was left in a given stage of a health insurance plan. Not exactly the coolest thing, but... hey. Still happy about it.
- moron4hire 1y agoThis is why I've always found it weird that people consider D3 to be a charting tool. Yes, people have used it to build a lot of charts, but it's really just a streaming data processing tool. It doesn't provide anything specific to charting[0]. All of that part, you're still left to figure out on your own. [0] At least in the core, I'm not too familiar with the full ecosystem and what is considered official in terms of plugins. Everytime I've tried to use it, I've not found the documentation leading me to using anything more specifically oriented towards charting.
- digitalWestie 1y agoThis is the answer. People need to consider D3 more as a graphics/dom manipulation library than a charting library.
- deleted 1y ago[deleted]
- gedy 1y agoYeah I used to pull my hair when a team would start down the D3 path for some non-interactive graphic, and then push back when I'd explain you can just use SVG for this simple case.
- TheHeasman 1y agoYaaasss. I think of it as being able to use a pencil to draw charts (and do creative stuff like Florence Nightingale's original polar area graph), instead of having a stencil that can draw things for you. It's a way to visually manipulate the DOM in a way if you're comfortable with data. You can simply just use Tableau or Power BI and take screenshots otherwise.
- joshcartme 1y agoAt least these days I think Plot, https://observablehq.com/plot/getting-started https://observablehq.com/plot/getting-started, which uses D3 under the hood and is from the makers of D3, is probably the closest thing to an official charting tool built on top of D3.
- draw_down 1y ago[dead]
- tmcw 1y agoAll right, I got nerdsniped into writing a "yes and" sort of thing even though I agree with the gist of this article :) https://macwright.com/2025/08/21/why-d3-is-so-verbose-another-angle https://macwright.com/2025/08/21/why-d3-is-so-verbose-anothe...
- TheHeasman 1y agoAhhhhh. Thanks man. And totally nerding out here because YES. ANIMATIONS. Animations is why I fell in love with wanting to learn D3 in 2019. You can do things as you transition between data steps, that honestly, has been such a pain in the behind to try with anything else. I'm not a web developer. I'm a data guy.
- fwip 1y agoSpeaking of animations, I used D3 to build my first web video game, a little match-3 game: https://fwip.github.io/colormatch/ https://fwip.github.io/colormatch/ The whole game board is a single SVG. It clearly has some bugs (like the score sometimes being NaN - no idea how I messed that up), but I haven't touched the code in over a decade, so it's a little time capsule.
- balamatom 1y agoI'd say because JavaScript is insufficiently expressive. No macros, no arrow (pipe) operator, and the premier way of writing it is 4x as verbose than what I'd consider reasonable. D3 is a great library though.
- DanielHB 1y agowhat do you mean by "arrow operator"?
- lionkor 1y agoMaybe overloadable operators like in C++, where -> usually demotes some kind of deeper access into the object or abstraction? Or, the opposite, and abstracted access.
- DanielHB 1y agoThat is what I thought, but that doesn't make sense for a language without pointers According to the other comment it seems he meant the |> pipe operator that is under proposal in js
- amiga386 1y agoProbably a reference to Clojure's arrow operator: https://blog.frankel.ch/learning-clojure/2/ https://blog.frankel.ch/learning-clojure/2/ Something like a(b(c(d(e(7)))))) in Javascript could be written (-> 7 e d c b a) in Clojure?
- balamatom 1y agoBingo.
- deleted 1y ago[deleted]
- TheHeasman 1y ago
- deleted 1y ago[deleted]
- biowaffeln 1y agorecently i've been having a lot of success with working with d3 + solid.js. I use d3 as the data processing layer, and solid for actually rendering svgs from the data. the combination is lovely, you get all the power of d3, while the parts that usually end up verbose are written succinctly in jsx. and it's a lot less pain than doing it in react, because the mental models of solid/d3 feel much more aligned
- TheHeasman 1y agoI'll check that out. At the moment I'm just building up a bunch of template code which I'll re-use. But might check out solid.js.
- skrebbel 1y agocan you elaborate a bit? how do you use d3 but not have it render svgs?
- mpyne 1y agoD3 renders using the logic you provide, and while it gives you a lot of helpers to make it easy to write SVG or HTML canvas tags, it's just as easy to tie it into other JS frameworks as well.
- Agent-Cooper 1y agoD3 provides a bunch of utilities for building visualizations beyond DOM manipulation. Here are some of the modules I use regularly: - d3-array: data processing - d3-scale: mapping from data attributes to visualization encodings - d3-scale-chromatic: color schemes - d3-shape: defining the shapes of paths, such for a line chart - d3-color: manipulating colors - d3-time: manipulating dates - d3-format: formatting numbers - d3-time-format: formatting dates These modules are useful even if you don't use D3 to manage the DOM. For example, you can use these utilities to help calculate all of the attributes for your SVG elements, but then use Svelte/React/Solid/Vue to create and render the SVG. If I'm building a visualization inside of a web app, I tend to prefer this approach since it leaves the framework in control of the DOM throughout the whole app. It feels simpler, especially if I want interactions in the visualization to modify the app's state.
- text0404 1y agoNote: the example is a misconception and not what's meant by "binding to data." In D3, binding to data refers to using the `.data()` method to supply an object (typically an array) which you can then use in a function callback in the accessors, so like `.attr('x1', d => /* access individual array item here */)`. This allows you to easily bind a dataset to a graphical representation and use its attributes to inform the properties of the visualization. I'd also argue that D3 is no more verbose than vanilla JS (at least for this example). What's the alternative for creating a line in SVG? const line = document.createElementNS('http://www.w3.org/2000/svg', 'line') line.setAttribute('x1', ...) line.setAttribute('y1', ...) line.setAttribute('x2', ...) line.setAttribute('y2', ...) // etc document.querySelector('svg').appendChild(line)
- TheHeasman 1y agoThis is very fair: I went for a metaphorical explanation, rather than a literal one. (For instance, I'd actually have had to write down the code for an SVG, and I was quickly writing this on my lunch break). The `.selectAll().data().join()` data binding method (or `.enter()` on older versions) is very intuitive once you understand it, but for the layman coming in, it's inaccessible AF. I fudged a little in my explanation to make it more accessible. But hey. That's learning.
- text0404 1y agoFor sure, data joining (and enter/exit) is arguably the learning curve wrt D3. TBH since I've started using FE frameworks which handle the DOM, d3-selection (and having to think about data binding) has almost completely fallen off my radar. Now it's mostly using functions from d3-scale, d3-geo, d3-shape, etc then mapping over that output to manually render DOM nodes.
- bapak 1y ago> I'd also argue that D3 is no more verbose than vanilla JS Right? So why load a bunch of JS to do the same thing? One step further, why load any JS at all since you're just generating an SVG? People have forgotten that HTML and SVG are meant to be DATA containers, you don't have to use JSON + JS. D3 is cool for the advanced visualizations and the interactivity. If you're sticking to static graphs, for the love of god just have the server serve a static SVG.
- yieldcrv 1y agoD3 is painful, we don't have to appeal to authority to admit that. Mike Bostock is an interesting person, and a case study in why we don't design languages from a single person's genius.
- z3ratul163071 1y agothe author was inspired by early directx apis
- ramesh31 1y agoBecause the alternative is big config files or a declarative DSL. Builder pattern works really well here to keep things simple.
- trjordan 1y agoMan, my first startup in 2010 used protovis, the charting library Mike Bostock built before deciding d3 was the better approach. It was rough to have an 8 month old startup with a core piece of tech that suddenly stopped improving. My main takeaway from so much of this is that "just a chart" is one of the biggest sources of hidden complexity in displaying useful information to people. It's right up there with "a simple web form" and "a web page with some simple interactivity." Everybody has a wildly different idea of what good looks like. Defaults will never be right. Personal and global taste changes annually. We clown react (rightly) for constantly reinventing the same 4 wheels, but customers gleefully use new stuff all the time. It's kind of amazing that d3 has been so durable in the frontend world. It really is a wrapper over a pretty solid approach. And yeah, that approach is complex, but that's the reality of visualization. It's hard to imagine another one that's that good.
- nchmy 1y ago> a core piece of tech that suddenly stopped improving. I just had this happen to me with something I had invested considerable time into. I've finally found a workaround, and even leveraged some of the previous tech, but man it sucks to have something just become abandonned. All the more reason to choose boring tech when you can...
- trjordan 1y agoNo fun to have to do a panic migration! Anyway my latest startup is trying to make AI do migrations, in no small part because of this problem 15 years ago.
- tiagod 1y agoI've worked a lot with dataviz over the years, and after fighting so many libraries, I've finally stabilised at plain d3. Even in React projects, I'll just use the d3 primitives and build SVG from that (ignoring all the d3 DOM stuff) All other libraries will just have a pile of abstractions that will leak everywhere as soon as you deviate from the happy path. If you just want a bunch of auxillary charts and don't need a ton of control, just use something like ECharts. When you want real creative control over your visualisations, don't bother with anything high level.
- time4tea 1y agoObservable plot. https://observablehq.com/plot/ https://observablehq.com/plot/
- dleeftink 1y agoVerbosity is readability. I'd wager some of the terser libraries take more effort picking up again after leaving them for a while. Whereas once the D3 training wheels come off, its muscle memory is hard to shed.
- sitzkrieg 1y agocame to post this. verbose good (to an extent)
- jwilber 1y agoLove all D3 content, but I'd add that the data binding just to create svg is not the real reason - after all, you can do this declaratively using most modern frameworks by directly iterating over the data and returning a positioned element (fwiw this is how I prefer to use it today). The reason is because of the complexity within d3 selection, namely the enter/update/exit + transition capabilities: https://www.d3indepth.com/enterexit/ https://www.d3indepth.com/enterexit/ Another thing worth mentioning that newcomers seem to take for granted - the margin boilerplate required for correct positioning (see https://observablehq.com/@d3/margin-convention https://observablehq.com/@d3/margin-convention).
- amdivia 1y agoIf you want to sacrifice some of the flexibility for less verbosity try out ObservableHQ's Plot [1] 1: https://observablehq.com/plot/ https://observablehq.com/plot/
- bsimpson 1y agoFor context, Observable is the startup from the original author of d3.
- Sweepi 1y agoI could not get over the fact that 0,0 in d3 is the top left corner instead of the bottom left. Why?? Everything in real life uses bottom left for 0,0! Probably because the first EGA/VGA accelerators worked this way to save one instruction in the most common use case and things never change....
- ayhanfuat 1y agoIt's not a d3 thing, it is an SVG thing. It's pretty much the standard for 2d computer graphics. Also same in CSS.
- Sweepi 1y agoI know that it is a SVG thing[1], but wouldnt that be a point of sth. like d3 - to be a software that gives me the option to choose my coordinate system origin with one line of code and deals with all the bullshit internally? [1] and before that, a "every screen is a CRT TV with a photon gun that 'draws' lines, starting in the top left"-thing
- antod 1y agoIt predates EGA. Most/all 8bit BASIC systems were top left, and they got it from somewhere earlier. Spreadsheets are top left, as are lots of other apps graphical or otherwise. The web (CSS, SVG etc). OpenGL etc etc. CRTs scanned downwards, most people read downwards. I would say that nearly everything in the real world (outside math) especially computer related uses top left as an origin.
- Sweepi 1y ago> I would say that nearly everything in the real world (outside math) especially computer related uses top left as an origin. I concede that point, its not want to meant, but I did express my point poorly. My point is: - A lot of things work like books[1]: top-left to bottom-right - However, 99+ % of graphs (anything from revenue numbers to health data) in all mediums (books, newspapers, websites) use a bottom-left origin. Never seen a revenue bar growing from top to bottom. In fact, I dont remember the last time i have seen a graph not using the I. Quadrant. Do you? - D3.js (imo) is a lib to create graphs from data, but does not abstract this problem away? Why? [1] "western/latin"-style books ofc
- blobbers 1y agoFirst of all, shocked people still use d3. Hasn't there been something better? It's pretty ancient by javascript standards. Do people still use jquery too? Haha... been about a decade since I touched this stuff! Second of all, isn't it ungodly slow? I get that it can draw a few boxes nicely, and maybe shuffle them around, but I had to write my own engine using html canvas because d3 couldn't get svg to flow properly if I had thousands of pixels in my image. Honestly, if you're going to go through the trouble of understanding d3, I would just write your own javascript canvas to animate things.
- wishinghand 1y agoVue is about as ancient yet people still use that. Python is even older.
- moi2388 1y agoBingo!
- stevage 1y agoI tried D3 a few times, with some success, but eventually abandoned it. The mental model it requires is so different from other charting libraries it seems too difficult for my brain to grasp for any period of time. Also, I've come to really dislike libraries that use this kind of `a.b().c()` chained form: boxplotContainer .append("line") .attr("x1", xScale(gender) - boxplotWidth/2) .attr("x2", xScale(gender) + boxplotWidth/2) I find it hard to reason about. What is the return value of boxplotContainer.append("line")? How do I debug it? What values can I inspect? That, and I really never got comfortable with the `.enter()` and `.exit()` and `.join()` concepts. It's so abstract.
- halfcat 1y ago> What is the return value of boxplotContainer.append("line")? How do I debug it? I don’t know D3, but usually in these chaining approaches it would be something like: boxplotContainer .append("line") .debug(callable_thing) .attr(…) Where debug() might be pipe() or some variation that lets you provide a callable where you can inspect the data (or drop into an interactive REPL, or whatever).