Context
I am migrating a "How to Build Wealth" blog post that was originally written as a Jupyter notebook on fastpages with plots generated using Altair. I need a charting library that integrates deeply with my React and Next.js stack.
The requirements are:
- Deep React Integration: The library should feel native to React (component-based, prop-driven) rather than a wrapper around an imperative library.
- Customizability: Ability to style charts to match the site's Tailwind CSS design system.
- Performance: Capable of handling reasonable datasets for personal finance without main-thread blocking.
- Responsiveness: Charts must adapt seamlessly to mobile and desktop viewports.
Decision
I will use Recharts for all data visualization on the site.
Recharts is a composable charting library built on React components. It uses SVG for rendering, which offers excellent scalability and accessibility.
Alternatives Considered
Non-React / Python-Centric Ecosystems
Plotly (React Wrapper):
- Pros: I have deep experience with this tool from multiple jobs and data science visualization work. Incredible power, scientific standard, interactive out of the box (pan/zoom), consistent with Python data science workflow.
- Cons: Massive bundle size (megabytes), API feels "foreign" in a React codebase (configuration objects vs components), distinct "Plotly look" that is hard to customize to match a specific brand without fighting the library.
- Why not: Too heavy and biased towards scientific apps. I want charts that look like my site, not like a Jupyter notebook.
Altair (Vega-Lite):
- Pros: The plots for the blog post already exist as Altair plots. Declarative grammar of graphics, immensely powerful for exploratory data analysis.
- Cons: primarily Python-based generation. Embedding in React often involves passing JSON specs to a Vega listener. Styling is constrained by the grammar and hard to marry with Tailwind.
- Why not: Great for analysis, poor for building bespoke custom frontend experiences.
React Ecosystem Competitors
Nivo:
- Pros: Built on D3, beautiful defaults, supports SVG, Canvas, and HTML layers.
- Cons: API is heavily configuration-object based. You pass a giant prop object to configure everything.
- Why not: Recharts' composable API (
<LineChart><Line /><XAxis /></LineChart>) is more readable and flexible to me than Nivo's configuration objects. It feels more "React-like."
Victory:
- Pros: robust, opinionated, good React Native support.
- Cons: Significantly less popular than Recharts, and their example page is much less impressive. Can be verbose.
- Why not: Subjective preference for Recharts' API composition style. Recharts has slightly higher adoption and community resources.
Chart.js (react-chartjs-2):
- Pros: Canvas-based (great for massive datasets with thousands of points), huge ecosystem.
- Cons: Canvas rendering makes CSS styling tricky (everything is inside the canvas). Responsive resizing can sometimes be finicky. The React wrapper is just a thin layer over the imperative Chart.js API.
- Why not: SVG (Recharts) is easier to style with CSS and debug in the DOM. I don't have massive datasets requiring Canvas performance.
Consequences
Positive:
- Composition: I can build complex charts by composing simple sub-components (
<XAxis />,<Tooltip />,<ReferenceLine />). - Styling: SVG elements are part of the DOM, meaning I can inspect them and often style them with CSS/Tailwind classes (though Recharts has its own prop styling system too).
- Responsiveness:
<ResponsiveContainer />handles resizing logic automatically. - Velocity: Rapid development of standard chart types (Line, Bar, Area, Pie).
Negative:
- Abstraction Leaks: It is a wrapper around D3. Sometimes you hit a wall and wish you had raw D3 access, or have to deal with quirks of the wrapper.
- Performance: SVG DOM nodes can get heavy if plotting thousands of points (unlike Canvas-based Chart.js).
- Animation Janky-ness: Complex animations can sometimes cause re-render loops or jank if not careful.