mrkeyoor.com_
Sat 08 Aug 21:01 UTC
npmWeb Frontendupdated 08 Aug 2026

@visx/group

@visx/group exports one React component, Group, that renders an SVG <g> container. It converts numeric left and top props into a translate(left, top) transform, always adds the visx-group class, accepts an optional full transform string, forwards ordinary SVG group attributes, and exposes the underlying SVGGElement through innerRef. It is a convenience layer for positioning chart regions, axes, marks, and labels, not a charting system or layout engine.

Verdict

A clean, tiny convenience for teams already building charts from visx primitives. Do not install it as a standalone chart solution, and consider a native <g> when translation sugar is the only feature you need.

API stability5/5The component surface is deliberately small: top, left, transform, className, children, innerRef, and forwarded SVG group props. Version 4 changed the supported React peer range but did not require runtime changes for React 18 or 19 consumers. The emitted class and transform behavior are visible in a short TypeScript source file, leaving little hidden state or lifecycle behavior to shift.
Docs4/5The package README explains the purpose, installation, and top and left shorthand in a few lines, while the generated visx docs expose props and the monorepo README supplies full chart examples and a v4 migration guide. The missing piece is candid detail on transform precedence, the always-present translate(0, 0), browser-only measurement timing, and when plain SVG is simpler.
Maintenance5/5Version 4.0.0 was published June 11, 2026, the airbnb/visx repository was pushed June 22, 2026, and the project documents v4 as its current stable release. The monorepo includes migration guidance, React 19 work, visual regression testing, and current package exports. Because releases cover many coordinated packages, consumers should still align visx major versions.
Ecosystem5/5@visx/group recorded 4,461,665 downloads from July 31 through August 6, 2026, and sits inside a 20,999-star visualization monorepo with scales, shapes, axes, text, gradients, tooltips, responsive helpers, and examples. It interoperates with normal React SVG children rather than requiring proprietary marks, so teams can mix native elements and other visx packages freely.

Use it if

  • You already compose charts from visx packages and want the same left and top positioning convention across components
  • You repeatedly write SVG groups with translate transforms for chart margins, series, axes, or small multiples
  • You want typed React SVG group props plus an explicit innerRef to the rendered SVGGElement
  • You prefer a low-level primitive that leaves scales, marks, animation, accessibility, and interaction under your control
Skip it if

Setup reality

Install with npm install @visx/group. Version 4.0.0 has one runtime dependency, classnames, and peer dependencies on React 18 or 19 plus optional matching @types/react. A React 16 or 17 project should remain on visx 3 rather than forcing the peer range. The package publishes CommonJS and ESM entry points, an exports map, and bundled TypeScript declarations, so ordinary modern bundlers need no config. The component does not create an <svg>; Group always emits <g>, and using it outside an SVG produces no visible chart. Its default transform is translate(left, top), with missing offsets treated as zero. Passing any truthy transform string replaces both offsets instead of composing with them. An empty transform string is also not a way to remove the attribute because the implementation falls back to translate(0, 0). The component always prepends the visx-group class through classnames. Other SVG attributes and event handlers are forwarded, but Group does not calculate margins, bounds, scales, clipping, responsiveness, hit areas, focus behavior, or ARIA labels. The ref prop documented by this package is innerRef, and it points at the actual SVGGElement after mount. Server rendering is straightforward because output is plain SVG markup, but measurements from getBBox still require a browser layout pass in an effect. Installing only @visx/group does not install @visx/shape, @visx/scale, axes, tooltips, or mock data; add those packages separately and keep all visx packages on compatible major versions.

Patterns

Offset SVG children with left and toptranslate-group

import { Group } from '@visx/group'

<svg width={320} height={180}>
  <Group left={24} top={16}>
    <circle cx={20} cy={20} r={12} fill="tomato" />
  </Group>
</svg>

Group renders transform="translate(24, 16)". It does not change the SVG viewport or reserve layout space.

Create an inner chart area from marginsapply-chart-margins

const margin = { top: 20, right: 16, bottom: 32, left: 48 }
const innerWidth = width - margin.left - margin.right
const innerHeight = height - margin.top - margin.bottom

<svg width={width} height={height}>
  <Group left={margin.left} top={margin.top}>
    <rect width={innerWidth} height={innerHeight} fill="none" />
  </Group>
</svg>

Group only applies the offset. Your code remains responsible for subtracting margins from scale ranges and mark dimensions.

Nest groups for local coordinate systemsnest-coordinate-systems

<Group left={margin.left} top={margin.top}>
  <Group left={plotX} top={plotY}>
    {points.map((point) => (
      <circle key={point.id} cx={point.x} cy={point.y} r={3} />
    ))}
  </Group>
</Group>

SVG transforms compose through nesting. The inner point coordinates are relative to both translations.

Supply a complete SVG transformset-custom-transform

<Group transform="translate(120 80) rotate(-30) scale(1.2)">
  <rect x={-20} y={-8} width={40} height={16} />
</Group>

A truthy transform overrides top and left completely. Put translate in the transform string when rotation or scale must follow an offset.

Group each data seriesrender-series-groups

{series.map((item, seriesIndex) => (
  <Group
    key={item.id}
    className="chart-series"
    top={seriesIndex * rowHeight}
    data-series-id={item.id}
  >
    <path d={item.path} fill={item.color} />
  </Group>
))}

Use stable data keys. Group forwards data attributes and combines your class with its built-in visx-group class.

Apply inherited SVG presentationstyle-group

<Group className="muted-series" fill="#64748b" stroke="currentColor" opacity={0.7}>
  <circle cx={10} cy={10} r={4} />
  <circle cx={30} cy={20} r={4} />
</Group>

Many SVG presentation attributes inherit to children, but a child's explicit fill, stroke, or opacity can override the group.

Attach React events to a grouphandle-pointer-events

<Group
  role="button"
  tabIndex={0}
  onClick={() => selectSeries(series.id)}
  onKeyDown={(event) => {
    if (event.key === 'Enter' || event.key === ' ') selectSeries(series.id)
  }}
>
  {marks}
</Group>

Group forwards handlers but supplies no keyboard semantics. Add role, focusability, key handling, and an accessible name when the group is interactive.

Give a graphic group an accessible labellabel-accessibly

<Group role="img" aria-labelledby="revenue-title revenue-desc">
  <title id="revenue-title">Monthly revenue</title>
  <desc id="revenue-desc">Bars from January through June</desc>
  {bars}
</Group>

The component adds no accessibility metadata. Test SVG title and description behavior with the browsers and assistive technologies your application supports.

Apply an SVG clip path to grouped marksclip-chart-marks

<svg width={width} height={height}>
  <defs>
    <clipPath id="plot-clip">
      <rect width={innerWidth} height={innerHeight} />
    </clipPath>
  </defs>
  <Group left={margin.left} top={margin.top} clipPath="url(#plot-clip)">
    {marks}
  </Group>
</svg>

Use a unique clipPath id per rendered chart, especially with server rendering or repeated dashboard widgets, to avoid document-wide ID collisions.

Measure the rendered SVG groupmeasure-group

import { useLayoutEffect, useRef } from 'react'
import { Group } from '@visx/group'

const groupRef = useRef<SVGGElement>(null)
useLayoutEffect(() => {
  const bounds = groupRef.current?.getBBox()
  if (bounds) console.log(bounds)
}, [])

return <Group innerRef={groupRef}>{marks}</Group>

getBBox requires browser SVG layout and is unavailable during server rendering. Measure after mount and account for later font or data changes.

Place a bottom axis in chart coordinatesposition-axis

import { AxisBottom } from '@visx/axis'

<Group left={margin.left} top={margin.top}>
  {marks}
  <Group top={innerHeight}>
    <AxisBottom scale={xScale} />
  </Group>
</Group>

@visx/axis is a separate installation. Keep its major version compatible with @visx/group and pass the same scale used for marks.

Replace the helper with native SVG when appropriateuse-native-group

const transform = `translate(${left}, ${top})`

<g className="series" transform={transform}>
  {children}
</g>

This native form covers the main behavior without a dependency. Prefer it when your project does not otherwise use visx conventions.

Alternatives

PackageRegistryPick it when
rechartsnpmUse when you want composed React charts with axes, tooltips, legends, responsiveness, and animation supplied as a higher-level system
victorynpmUse when a declarative React chart suite is a better fit than assembling low-level SVG primitives yourself
d3-selectionnpmUse when React is not driving SVG ownership and you want D3's selection, data join, and direct DOM grouping model