Visx logo

Visx

A collection of expressive, low-level visualization primitives for React, developed by Airbnb.

npm install @visx/visx
20.4K53.3K/weekv3.12.012 KBMIT141 issues
Last updated: 2024-11-08
Star history chart for airbnb/visx

TL;DR

Unlike traditional charting libraries, Visx provides low-level visualization primitives (shapes, axes, gradients) that let you build your own reusable chart components.

It combines the mathematical power of D3 for layout calculations with React for efficient DOM updates, keeping bundle sizes extremely small.

Why Visx?

Visx (short for visualization components) is distinct because it is not a charting library in the traditional sense. It is a set of unopinionated modules that give you the building blocks to create your own charts.

  • "Bring Your Own State": Visx handles the math and the rendering primitives, but it doesn't dictate how you manage state, animation, or interaction. You can plug in react-spring, framer-motion, or standard React state seamlessly.
  • Modular & Lightweight: The library is split into multiple small packages (e.g., @visx/shape, @visx/scale, @visx/axis). You only install exactly what you need, keeping your bundle size minimal.
  • D3 Power, React DOM: It leverages D3 for complex calculations (like computing paths for a streamgraph) but leaves the actual DOM updating to React. This avoids the common "D3 vs. React" fight over DOM control.
  • Infinite Flexibility: Since you are composing low-level SVG elements (<rect>, <path>), you have absolute control over styling, layout, and behavior. You are not limited by a library's configuration options.
  • TypeScript Native: Written in TypeScript, it provides excellent type safety for complex data shapes and scales.

Code Snippet

Writing Visx code feels like writing SVG manually, but with helper components. Note how we explicitly define scales and dimensions.

import { useMemo } from 'react';
import { Bar } from '@visx/shape';
import { Group } from '@visx/group';
import { scaleBand, scaleLinear } from '@visx/scale';

const data = [
  { letter: 'A', frequency: .08167 },
  { letter: 'B', frequency: .01492 },
  { letter: 'C', frequency: .02782 },
];

// Accessors
const getLetter = (d) => d.letter;
const getFrequency = (d) => d.frequency;

function BarChart({ width, height }) {
  // Bounds
  const xMax = width;
  const yMax = height - 50;

  // Scales
  const xScale = useMemo(
    () =>
      scaleBand({
        range: [0, xMax],
        domain: data.map(getLetter),
        padding: 0.4,
      }),
    [xMax],
  );
  
  const yScale = useMemo(
    () =>
      scaleLinear({
        range: [yMax, 0],
        domain: [0, Math.max(...data.map(getFrequency))],
      }),
    [yMax],
  );

  return (
    <svg width={width} height={height}>
      <Group top={20}>
        {data.map((d) => {
          const letter = getLetter(d);
          const barWidth = xScale.bandwidth();
          const barHeight = yMax - yScale(getFrequency(d));
          const barX = xScale(letter);
          const barY = yMax - barHeight;
          
          return (
            <Bar
              key={`bar-${letter}`}
              x={barX}
              y={barY}
              width={barWidth}
              height={barHeight}
              fill="rgba(23, 233, 217, .5)"
            />
          );
        })}
      </Group>
    </svg>
  );
}

As you can see, Visx requires you to wire up the geometry yourself, offering maximum transparency.

Pros and Cons

No library is perfect; understanding the trade-offs is key to selecting the right tool.

Pros

  • Total Control: If you can imagine it in SVG or D3, you can build it in Visx. You are never blocked by an API that doesn't support a specific customization.
  • Bundle Size: Because you only import specific packages (e.g., @visx/gradient), you avoid shipping unused charting code to your users.
  • Learning Tool: It is an excellent way to learn how data visualization actually works under the hood without getting lost in D3's imperative API.

Cons

  • Steep Learning Curve: You need to understand data visualization concepts (scales, domains, ranges) and SVG attributes. It is not "plug and play."
  • Verbosity: Building a simple bar chart with axes, tooltips, and legends requires significantly more code than Recharts or Nivo.
  • No "Default" Look: You start with a blank canvas. You have to style everything yourself, which slows down initial development speed.

Comparison with Other Charting Libraries

The table below outlines the positioning differences between Visx and other popular visualization libraries:

LibraryDesign PhilosophyBest ForPain Points
VisxPrimitives & Toolset
Unopinionated building blocks, minimal abstraction.
Bespoke Viz
Creating a custom UI library or unique visualizations that defy standard patterns.
High Effort
Requires writing a lot of boilerplate code to get basic charts working.
RechartsHigh-Level Components
Easy-to-use, composable chart wrappers.
Standard Dashboards
Quickly building standard admin panels with minimal configuration.
Flexibility
Hard to break out of the "box" if you need a chart type they don't support.
NivoConfiguration Heavy
One mega-component per chart type with many props.
Beautiful Defaults
Projects that need high-polish visuals and animation without custom code.
Bundle Size
Can be heavy if not careful with imports; props API is vast.

Verdict: When to Adopt

Adopt Visx if you are building a product where data visualization is a core differentiator (e.g., a fintech trading platform or a specialized analytics tool). It is the best choice for Senior Engineers who want to build their own internal charting library on top of robust primitives. If you just need a "Good Enough" line chart for an admin panel, use Recharts or Nivo instead.