# D3.js vs Recharts: When to Use Each (And When to Combine Them)
By Govind Bajaj · 2025

Tags: d3, recharts, data-visualization, react, charts
I rebuilt the same chart in D3 and Recharts. One took 4 hours and 400 lines. The other took 20 minutes and 40 lines. But only one could do what I actually needed.
I rebuilt the same custom analytics chart in both D3.js and Recharts last month.

The D3 version took four hours and four hundred lines of code. It had full control over every pixel, custom animations, and complex interactions.

The Recharts version took twenty minutes and forty lines. It rendered correctly, responded to window resize, and supported tooltips out of the box.

But only the D3 version could do what I actually needed: a brushable timeline with synchronized cross-chart highlighting. Recharts does not expose the primitives for that level of interactivity.

## The Fundamental Difference

Recharts is a React charting library built on D3. It provides pre-built components for common chart types: LineChart, BarChart, PieChart, AreaChart. You compose them declaratively, like any React component.

D3 is a low-level data visualization toolkit. It provides utilities for scales, shapes, selections, transitions, and interactions. You build charts from scratch, imperatively manipulating SVG or Canvas.

Use Recharts when you need standard charts quickly. Use D3 when you need custom visualizations that no library supports.

## When Recharts Is the Right Choice

Recharts excels at standard business charts. Line charts for trends, bar charts for comparisons, pie charts for proportions, area charts for cumulative data. If your design mockup looks like something from Excel or Tableau, Recharts can build it in minutes.

The Royal Madrasi dashboard uses Recharts for sales trends, order volume by hour, and revenue by category. These are standard charts. Recharts handles them with minimal code.

```tsx
import { BarChart, Bar, XAxis, YAxis, Tooltip, ResponsiveContainer } from 'recharts'

function HourlyOrders({ data }: { data: HourlyData[] }) {
  return (
    <ResponsiveContainer width="100%" height={300}>
      <BarChart data={data}>
        <XAxis dataKey="hour" />
        <YAxis />
        <Tooltip />
        <Bar dataKey="orders" fill="#059669" />
      </BarChart>
    </ResponsiveContainer>
  )
}
```

## When D3 Is the Right Choice

D3 is necessary for custom visualizations that no charting library supports. Brushable timelines, force-directed graphs, geographic visualizations, network diagrams, hierarchical tree layouts, and custom animations all require D3's low-level control.

The Sans Herbals analytics dashboard has a custom funnel visualization showing conversion rates across five stages. No charting library supports this out of the box. D3 builds it precisely.

## The Hybrid Approach: D3 Inside React

You do not have to choose one or the other. The most productive pattern is Recharts for standard charts, D3 for custom ones, in the same application.

For a custom chart that needs React integration, use D3 for calculations and React for rendering:

```tsx
import { useMemo } from 'react'
import { scaleLinear, scaleTime } from 'd3-scale'
import { line, area } from 'd3-shape'

function CustomChart({ data, width, height }: ChartProps) {
  // D3 handles the math
  const xScale = useMemo(() =>
    scaleTime().domain(extent(data, d => d.date)).range([0, width]),
    [data, width]
  )

  const yScale = useMemo(() =>
    scaleLinear().domain([0, max(data, d => d.value)]).range([height, 0]),
    [data, height]
  )

  const linePath = useMemo(() =>
    line<DataPoint>()
      .x(d => xScale(d.date))
      .y(d => yScale(d.value))
      (data),
    [data, xScale, yScale]
  )

  // React handles the rendering
  return (
    <svg width={width} height={height}>
      <path d={linePath} fill="none" stroke="#059669" strokeWidth={2} />
    </svg>
  )
}
```

D3 calculates scales and path data. React renders SVG elements. This gives you D3's power with React's component model.

## Performance Comparison

FactorRechartsD3HybridLines of code40400150Development time20 min4 hours1 hourCustomizationLimitedUnlimitedHighReact integrationNativeManualGoodBundle size\~70KB\~90KB (modular)\~40KB

## Takeaways

- Recharts for standard charts (line, bar, pie) — fast development, less code
- D3 for custom visualizations no library supports — full control, more code
- The hybrid approach (D3 math + React rendering) is the sweet spot for custom charts
- Import D3 modules individually (d3-scale, d3-shape) to minimize bundle size
- Recharts is built on D3 — you are not choosing different technologies, just different abstraction levels
- Start with Recharts. Reach for D3 only when Recharts cannot do what you need
- The same chart in D3 takes 10x the code but gives 100x the flexibility