Tom MacWright

Mixing d3 and React

tl;dr: Use JSX instead of the d3 selection API and keep everything else.

I have lots of love for both React and d3. Recently I was tasked with building a few data-visualization dashboards, and combined the two. From my understanding of the two technologies, the way I mushed them together was the simplest possible way, but after completing the project and reading prior art, it’s a bit different than most. So here’s my flavor of React+d3 intermingling.

This is one of the first times a Venn Diagram has seemed appropriate, and I have no intention of missing it.

DOM ManipulationMathScalesLayoutsUtilitiesEtc.ComponentsServer RenderingReactd3

d3 includes everything necessary to create charts: it includes DOM manipulation, scales, algorithms, parsers, and much more. Especially in the world of d3 version 4, you can mix & match d3’s parts with other software, using only those you want to.

That’s the key to mixing d3 & React: use React for DOM manipulation. Sure, React has a technique for intermixing with other libraries and you can reference elements in the DOM, but in my experience these are last resorts.

That’s it: I think porting d3-based DOM manipulation code to React’s JSX code is the simplest and best way to mix the two libraries.

Other Approaches

There are other ways that other people have promoted - imitating d3’s API, wrapping around React’s lifecycle methods, or even wrapping d3 in components. I think these approaches fall into two traps: using d3’s selection logic where it isn’t necessary and having two ways to build a page, and over-abstracting d3’s extremely flexible visualization logic into less flexible components with hard assumptions.


I’ll start with Mike Bostock’s pie chart update block.

Here’s the code, annotated with whether it needs to be changed or not:

In terms of the value that we derive from d3 - the parts that would be hard to write from scratch without a library - the vast majority here is in the brilliantly-implemented scale and layout methods, and the methods that generate SVG paths. All of those methods work perfectly with React. They’d even work really well with jQuery or another tookit: they’re agnostic to the DOM implementation.

Here’s that example, in React:

Except for the part where we interact with the DOM, the code is the same.

Here’s the process I take to make this port:


In my opinion, this approach has several major advantages over others:


Most of d3’s interaction with the DOM is rooted in the selection API, but there are a few other substantive places where it builds DOMs for you. The one I’ve bumped into the most is the axis code, which draws ticks and axis lines. Luckily, it’s only around 100 lines ported to React - here’s what I’ve been working with.


The elephant in the room, for some, is animation. d3 is very concerned with making animation possible and its selection API reflects that fact. Personally I avoid animation whenever possible, and so I haven’t invested much time getting it to work with this approach: but it’s likely possible with Cheng Lou’s phenomenal react-motion project.

October 11, 2016 @tmcw