mrkeyoor.com_
Wed 23 Sept 02:53 UTC
npmWeb Frontendupdated 22 Sept 2026

@visx/grid review

@visx/grid 4.0.0 contains React components that turn scale ticks into SVG chart lines. `GridRows` draws horizontal rules, `GridColumns` draws vertical ones, and `Grid` combines them; angle, radial, and polar components cover circular layouts. You supply the scales, plot dimensions, tick choices, and paint. Version 4 adds React 19 support and modern package exports while dropping React 16/17 and runtime PropTypes. The package does not draw data marks, axes, labels, tooltips, legends, or a responsive container.

Verdict

@visx/grid 4.0.0 installed in 4.3 seconds with no audit findings, but our import brought 35 packages and measured 15.8 KB gzipped for grid primitives alone. Install it when shared visx scales and custom SVG composition justify that cost; choose a higher-level chart library or hand-written lines when they do not.

We installed it

Lab card: what happened when we installed @visx/gridScreenshot of @visx/grid documentation
Install✓ · 4.3s35 packages on disk · 8 MB
ImportESM import works · require() works · CommonJS package with exports map
Browser15.8 KBgzipped (44 KB minified), bundled with esbuild
TypesTypeScript types bundled
Known vulns00 critical · 0 high · 0 moderate · 0 low (npm audit)

Answers from our run

Does @visx/grid install cleanly?

Yes. In a fresh container with an empty cache, npm install @visx/grid finished in 4 seconds, leaving 35 packages and 8 MB on disk. npm audit reported no known vulnerabilities.

How much does @visx/grid add to a browser bundle?

15.8 KB gzipped (44 KB minified) when the whole package is bundled for the browser with esbuild. Importing only part of it is usually smaller.

Does @visx/grid work with both ESM and CommonJS?

Yes. Both import '@visx/grid' and require('@visx/grid') worked in Node 22 in our run. The package is published as CommonJS with an exports map.

Does @visx/grid include TypeScript types?

Yes, type declarations ship inside the package, so no @types install is needed.

@visx/grid or recharts: which should you use?

recharts: Choose it when a React chart should include CartesianGrid, axes, common series, legends, and responsive layout. @visx/grid 4.0.0 installed in 4.3 seconds with no audit findings, but our import brought 35 packages and measured 15.8 KB gzipped for grid primitives alone.

When should you not use @visx/grid?

You want a chart component from a data array: this package supplies grid primitives and leaves axes, series, legends, tooltips, and layout to other code

API stability4/5The grid package still revolves around six focused components, scale props, dimensions, tick values, styles, and render callbacks. Version 4 made the package boundary stricter rather than redesigning those components: root exports now define the supported surface, deep imports are blocked, React 18 or 19 is required, and runtime PropTypes are gone. The migration guide also says to move all visx packages to v4 together, so a seemingly local grid upgrade can affect the rest of a chart stack.
Docs4/5The direct grid documentation returned HTTP 200, and the package README gives the minimum combined-grid example with both scales and dimensions. The v4 migration guide spells out React ranges, optional React type peers, package-root imports, browser support, strict ESM output, and removed PropTypes. Component declarations cover row, column, angle, radial, and polar props. A newcomer still has to combine several visx pages to learn margins, responsive measurement, axes, accessible SVG, and layer order.
Maintenance5/5Version 4.0.0 was published on 2026-06-11, followed by a repository push on 2026-06-22. The release added React 19 support, resolved dependency alerts, repaired strict ESM packaging, removed old browser assumptions, and documented a full migration path. Airbnb's unarchived monorepo has 21,022 stars. GitHub reports 148 open issues and pull requests across all visx packages, so that queue cannot be read as grid-specific defects, but it does show the maintenance scope of the collection.
Ecosystem5/5The npm endpoint counted 4,544,682 downloads for @visx/grid in the latest week. It sits beside official visx packages for scale, axis, group, shape, responsive sizing, tooltip, annotation, geo, and hierarchy, while accepting the D3-style scales used throughout that collection. React 18 and 19, CommonJS, ESM, and bundled declarations are covered. The tradeoff is composition work: ecosystem pieces remain separate installs and do not become a ready-made chart merely because their versions match.

Use it if

  • A custom React SVG chart needs gridlines calculated from the same scales used by its marks and axes
  • Rows and columns need exact tick arrays, separate styling, or a custom line render function
  • A radar or radial chart needs reusable spoke and ring geometry
  • The application already uses visx 4 and accepts responsibility for chart sizing, layering, and semantics
Skip it if

Setup reality

In our sandbox, @visx/grid 4.0.0 installed in 4.3 seconds and left 35 packages using 8 MB. The package has 6 direct dependencies, 2 peer dependencies, bundled TypeScript declarations, and a 208 KB unpacked size. npm audit reported 0 known vulnerabilities. It is CommonJS with an exports map; both require() and ESM import worked. Our browser import measured 44 KB minified and 15.8 KB gzipped.

React 18 or 19 is required, and @types/react is the optional second peer for TypeScript projects. Upgrade all @visx/* dependencies to version 4 together because their entry points and internal package ranges moved as a set. Deep imports such as @visx/grid/lib/... are blocked by the exports map; use symbols from @visx/grid. JavaScript apps get no generated PropTypes in v4, so invalid scales or dimensions have no runtime validation layer from visx.

A grid needs ready-made scales plus plot width and height. Those dimensions should describe the inner plot after margins, and the scale ranges must use that same box. numTicks is a request to the scale, not a fixed count; pass tick values when the exact lines matter. Band-scale gridlines are centered within each band. SVG paint order is literal, so render a decorative grid before data marks and set pointerEvents='none' plus aria-hidden='true'.

Responsiveness comes from @visx/responsive or your own observer, not this package. Avoid drawing until the measured width and height are positive, especially around server rendering and the first browser layout. Polar components expect angle output in radians and a separate radial scale; explicit ticks prevent odd rings from domain-derived values. There is no theme context, clipping rule, axis synchronization, or transition system in @visx/grid 4.0.0.

Patterns

Draw rows and columns draw-cartesian-grid

import { Grid } from '@visx/grid'
import { scaleLinear } from '@visx/scale'

const width = 640
const height = 320
const xScale = scaleLinear({ domain: [0, 100], range: [0, width] })
const yScale = scaleLinear({ domain: [0, 1], range: [height, 0] })

<svg width={width} height={height}>
  <Grid xScale={xScale} yScale={yScale} width={width} height={height}
    numTicksRows={5} numTicksColumns={10} />
</svg>

The scale ranges and grid dimensions must describe the same plot box; requested tick counts remain approximate.

Render horizontal rules only draw-horizontal-grid

import { GridRows } from '@visx/grid'

<GridRows
  scale={yScale}
  width={plotWidth}
  numTicks={6}
  stroke='#d7dde5'
  strokeWidth={1}
/>

`GridRows` takes a y-position scale and draws each result from x=0 to the supplied width.

Center rules inside category bands draw-band-columns

import { GridColumns } from '@visx/grid'
import { scaleBand } from '@visx/scale'

const xScale = scaleBand({
  domain: ['Mon', 'Tue', 'Wed'],
  range: [0, plotWidth],
  padding: 0.2,
})

<GridColumns scale={xScale} height={plotHeight} />

For a band scale, `GridColumns` adds half of `bandwidth()` so each rule crosses the band center.

Use exact grid values set-grid-ticks

<Grid
  xScale={xScale}
  yScale={yScale}
  width={plotWidth}
  height={plotHeight}
  columnTickValues={[0, 25, 50, 75, 100]}
  rowTickValues={[0, 0.5, 1]}
/>

Explicit arrays replace the scale's approximate tick selection and must contain values each scale accepts.

Style rows and columns separately style-grid-directions

<Grid
  xScale={xScale}
  yScale={yScale}
  width={plotWidth}
  height={plotHeight}
  stroke='#94a3b8'
  strokeDasharray='3 4'
  rowLineStyle={{ opacity: 0.55 }}
  columnLineStyle={{ opacity: 0.25 }}
/>

Shared SVG stroke props reach both directions; `rowLineStyle` and `columnLineStyle` override each set.

Translate the inner plot once align-chart-margins

import { Group } from '@visx/group'

const margin = { top: 20, right: 24, bottom: 40, left: 48 }
const plotWidth = width - margin.left - margin.right
const plotHeight = height - margin.top - margin.bottom

<svg width={width} height={height}>
  <Group left={margin.left} top={margin.top}>
    <Grid xScale={xScale} yScale={yScale} width={plotWidth} height={plotHeight} />
    {marks}
  </Group>
</svg>

Set both scale ranges from `plotWidth` and `plotHeight`. Reapplying the margin inside the grid shifts lines away from marks.

Put gridlines behind chart data hide-decorative-grid

<svg width={width} height={height}>
  <Grid
    xScale={xScale}
    yScale={yScale}
    width={width}
    height={height}
    aria-hidden='true'
    pointerEvents='none'
  />
  <DataSeries data={data} />
</svg>

SVG paints in document order. Rendering the grid first keeps it behind marks, while the two props remove decorative lines from hit testing and the accessibility tree.

Replace default row elements render-custom-rows

<GridRows scale={yScale} width={plotWidth} tickValues={[0, 25, 50, 75, 100]}>
  {({ lines }) => (
    <g>
      {lines.map(({ from, to, index }) => (
        <line key={index} x1={from.x} y1={from.y} x2={to.x} y2={to.y}
          stroke={index === 0 ? '#334155' : '#cbd5e1'}
          strokeWidth={index === 0 ? 2 : 1} />
      ))}
    </g>
  )}
</GridRows>

A child render function replaces the default line elements. Keep tick ordering stable when using the generated index as the React key.

Measure the chart container measure-responsive-grid

import { ParentSize } from '@visx/responsive'

<ParentSize debounceTime={100}>
  {({ width, height }) => {
    if (width < 1 || height < 1) return null
    const xScale = makeXScale(width)
    const yScale = makeYScale(height)
    return <svg width={width} height={height}>
      <Grid xScale={xScale} yScale={yScale} width={width} height={height} />
    </svg>
  }}
</ParentSize>

Container measurement belongs to `@visx/responsive`; server output and the first browser pass may not have a positive size.

Draw radial chart spokes draw-angle-spokes

import { GridAngle } from '@visx/grid'
import { scaleLinear } from '@visx/scale'

const angleScale = scaleLinear({ domain: [0, 8], range: [0, Math.PI * 2] })

<GridAngle scale={angleScale} tickValues={[0, 1, 2, 3, 4, 5, 6, 7]}
  innerRadius={24} outerRadius={140} left={160} top={160} />

The angle scale outputs radians. `GridAngle` rotates the coordinate conversion so angle zero appears at the top.

Draw concentric value rings draw-radial-rings

import { GridRadial } from '@visx/grid'
import { scaleLinear } from '@visx/scale'

const radiusScale = scaleLinear({ domain: [0, 100], range: [0, 140] })

<GridRadial scale={radiusScale} tickValues={[20, 40, 60, 80, 100]}
  left={160} top={160} stroke='#cbd5e1' fill='transparent' />

Explicit radial ticks prevent an unwanted center ring and keep the circles tied to meaningful data values.

Combine spokes and rings draw-polar-grid

import { GridPolar } from '@visx/grid'

<GridPolar
  scaleAngle={angleScale}
  scaleRadial={radiusScale}
  outerRadius={140}
  left={160}
  top={160}
  tickValuesAngle={[0, 1, 2, 3, 4, 5, 6, 7]}
  tickValuesRadial={[20, 40, 60, 80, 100]}
  strokeAngle='#e2e8f0'
  strokeRadial='#cbd5e1'
/>

`GridPolar` composes angle and radial grids; it does not infer compatible domains, radii, or center coordinates from data.

Alternatives

PackageRegistryPick it when
rechartsnpmChoose it when a React chart should include CartesianGrid, axes, common series, legends, and responsive layout.
victorynpmChoose it for declarative chart composition with axes, grids, themes, and animation in one system.
@nivo/linenpmChoose it when an opinionated line chart with interaction, legends, and SVG or Canvas rendering is preferable.

More web frontend guides

postcss · react · react-dom · tailwindcss · htmlparser2 · tailwind-merge · the whole shelf →

How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.