# airbnb/visx: low-level React visualization components you assemble yourself

> visx is a set of small React packages that wrap d3 math for scales, shapes and axes. It gives you chart primitives, not charts, and v4 requires React 18 or 19.

**airbnb/visx** — 🐯 visx | visualization components

- Repository: https://github.com/airbnb/visx
- Website: https://visx.airbnb.tech
- Stars: 21,071 · Forks: 769
- Language: TypeScript
- License: MIT
- Published: 2026-09-21 · Updated: 2026-09-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/airbnb-visx

## The problem visx solves: d3 math without d3 DOM ownership

Most React chart libraries hand you a component with props for series, colors and tooltips. That is fast until the chart needs something the library did not anticipate, at which point you fight the abstraction. visx takes the opposite path. It is a collection of reusable low-level visualization components, and the README states the goal plainly: to let you build your own reusable chart library or a custom one-off chart. Nothing renders a complete chart for you.

The intended audience is a team that already writes React and is willing to own SVG markup. The README describes the alternative it rejects: copying d3 code into a useEffect hook, which it calls mixing two mental models for updating the DOM. visx keeps d3 for calculations and React for rendering, so there are no selections and no enter/exit/update cycle. If you have never written a scale or positioned an SVG element, this library gives you fewer guardrails than a batteries-included charting package.

## How visx splits d3 math from React rendering

The package layout is the architecture. Each concern lives in its own npm package under packages/, so @visx/scale wraps d3-scale, @visx/shape provides primitives such as Bar, @visx/group positions children with a transform, and @visx/mock-data supplies sample datasets. You install only what a given chart needs, which is how the project keeps bundle sizes down.

The data flow in the README example is explicit. You define width, height and margins, compute xMax and yMax from them, build a scaleBand for the categorical axis and a scaleLinear for the value axis, then map over the data and render a Bar per row. The scale functions convert data values into pixel coordinates; React renders the resulting SVG. There is no internal state store and no chart-level component deciding layout for you. That is the trade-off: every axis, gridline and tooltip is your code.

The repository is a monorepo managed with lerna and Yarn workspaces, with vitest.config.ts for tests and TypeScript project files at the root. The root package.json is private and pins the toolchain: node >=24.0.0 and yarn >=4.0.0. Those constraints apply to contributors building the repo, not to applications installing published packages.

## Installing visx and drawing a first bar chart

visx publishes scoped packages on npm, and the README's quick start installs four of them plus mock data. Run this in an existing React project:

```bash
npm install --save @visx/mock-data @visx/group @visx/shape @visx/scale
```

With those installed, the README builds a bar graph from letterFrequency in @visx/mock-data. The example defines dimensions, derives xMax and yMax, and creates the two scales before rendering any element:

```javascript
import { letterFrequency } from '@visx/mock-data';
import { Group } from '@visx/group';
import { Bar } from '@visx/shape';
import { scaleLinear, scaleBand } from '@visx/scale';

const data = letterFrequency;
const width = 500;
const height = 500;
const margin = { top: 20, bottom: 20, left: 20, right: 20 };
const xMax = width - margin.left - margin.right;
const yMax = height - margin.top - margin.bottom;
```

The scales map letters to x positions and frequencies to y positions. scaleBand with round: true and padding: 0.4 produces evenly spaced bands; scaleLinear with range [yMax, 0] inverts the y axis so larger values sit higher on screen. The README uses accessors getLetter and getFrequency to read fields from each row.

Rendering is a plain SVG element with a map over the data. Each row becomes a Group wrapping a Bar, and the bar height is computed as yMax minus the scaled frequency:

```javascript
<svg width={width} height={height}>
  {data.map((d) => {
    const letter = getLetter(d);
    const barHeight = yMax - (yScale(getFrequency(d)) ?? 0);
    return (
      <Group key={`bar-${letter}`}>
        <Bar x={xScale(letter)} y={yMax - barHeight} height={barHeight} width={xScale.bandwidth()} fill="#fc2e1c" />
      </Group>
    );
  })}
</svg>
```

What you should see is a 500 by 500 SVG with one red bar per letter in the dataset. Note that the README example omits an axis; adding tick labels means composing additional visx packages or writing the text elements yourself.

## No animation, no chart wrapper, and other deliberate limits

The most cited limitation is stated by the project itself. The README's FAQ acknowledges that a common criticism of visx is that it does not have animation baked in, and calls that a conscious choice. The reasoning given is bundle size: if an app already bundles react-motion, a hypothetical @visx/animation package would be redundant, and since visx components are React components, any React animation library works with them. That is defensible, but it means a team that expects transitions out of the box will write them.

The second limit is the absence of a chart component. There is no BarChart with a data prop. If a product requirement is "show a bar chart by Friday," visx is the wrong tool; a higher-level library gets there faster. visx pays off when the chart is the product and the default look is unacceptable.

Version constraints are a real gate. The README marks v4 as the current stable release and states it requires React 18 or 19. Projects still on React 17 cannot adopt v4 without upgrading React first, and the README points v3 users to MIGRATION.md. The jump from v3.12.0 to v4.0.0 also skipped a long gap; v3.11.0 shipped in May 2024 and v3.12.0 in November 2024, so anyone on an early v3 release should read the migration guide rather than assume a drop-in upgrade.

## visx compared with a higher-level React charting library

Recharts is the obvious counterexample: it exposes composed components such as LineChart and Bar with a data prop, and it handles axes, tooltips, legends and responsive sizing internally. The difference is where control sits. With Recharts you configure a chart that already exists; with visx you assemble SVG elements and decide every coordinate.

That has consequences in both directions. Recharts gets a standard chart on screen in a few lines, but custom marks, unusual layouts or precise control over tick rendering can require escaping its component tree. visx gives you the coordinate system and the Bar primitive and nothing else, so unusual layouts are the normal case rather than a workaround. It also means accessibility, empty states and responsive resizing are yours to implement.

A second option is d3 directly. visx exists precisely because the README considers copying d3 into useEffect a poor fit for React's update model. If your team is comfortable with d3 selections and does not want React to own the DOM, plain d3 remains valid; visx is for teams that want d3's math and React's rendering in the same component.

## Maintenance, upgrades and the MIT licence

The repository is not archived, and the last push was on 2026-06-22, three months before this writing, so the project is still receiving commits. v4.0.0 was released on 2026-06-11, which means the current major line is recent. The release history also shows the cadence is uneven: v3.11.0 in May 2024, v3.12.0 in November 2024, then a gap to v4.0.0 in June 2026. Plan upgrades around majors rather than expecting frequent minor releases.

For consumers, the upgrade cost concentrates on the React peer dependency. v4 requires React 18 or 19, so the migration is often a React upgrade wearing a visx hat. MIGRATION.md is the document to read before touching package.json. Because visx is split into many packages, an upgrade means bumping each @visx package you actually installed, and the README's guidance to pick only the packages you need keeps that list short.

Licensing is straightforward: the repository carries an MIT licence, and the root package.json declares "license": "MIT". MIT permits commercial use and modification with the licence and copyright notice retained. That is a description of the licence text, not legal advice; check with your own counsel if your organization has specific open source policies.

## Conclusion

Adopt visx when your team already writes React and wants to own chart markup, styling and animation rather than configure a chart library. Skip it when you need a finished chart in an afternoon, or when a designer expects built-in transitions: visx ships no animation layer. Before committing, install @visx/shape and @visx/scale against a React 18 or 19 app, render the README bar example with real data, and read MIGRATION.md if you are coming from v3.

## FAQ

### How does visx work?

visx uses d3 for calculations and React for rendering the DOM. You build scales such as scaleBand and scaleLinear, map over your data, and render SVG elements like Bar inside a Group. The README states there are no d3 selections or enter/exit/update cycles.

### Do I have to install every visx package to make a chart?

No. The README's FAQ says to pick and choose the packages you need, which is how the project keeps bundle sizes down. The bar chart example installs @visx/mock-data, @visx/group, @visx/shape and @visx/scale.

### Does visx support animation or transitions?

Not built in. The README calls the lack of baked-in animation a conscious choice made for bundle size, and notes that because visx components are React components, any React animation library can be used alongside them.

### Which React versions does visx v4 require?

The README states that visx v4 is the current stable release and requires React 18 or 19. Upgrading from v3 is covered in MIGRATION.md.

### Does visx work with Preact?

The README's FAQ says yes, by aliasing react and react-dom to preact/compat. For v4 it adds that you should configure your package manager to satisfy the React 18/19 peer dependency range.

## Sources

- [airbnb/visx on GitHub](https://github.com/airbnb/visx)
- [License: MIT](https://github.com/airbnb/visx/blob/master/LICENSE)
- [Project website](https://visx.airbnb.tech)
- [README](https://github.com/airbnb/visx/blob/master/README.md)
- [Releases](https://github.com/airbnb/visx/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/airbnb-visx
