visx
Use this skill when work touches Airbnb visx (@visx/*) — low-level React visualization primitives, @visx/xychart, interaction packages, specialized layouts, or v3→v4 migration.
Treat 4.0.0 as the published stable line (React 18/19). Prefer package-root imports, gallery sandboxes at the installed tag, and GitHub/visx.airbnb.tech over stale deep-import snippets. Mark 4.1 packages (@visx/theme, @visx/a11y, @visx/chart, @visx/kernel, registry) as not installable until they appear on npm.
Workflow
- Confirm the local surface before changing code:
- All
@visx/*versions aligned on the same major (prefer^4.0.0); do not mix v3 and v4. - React peers
^18 || ^19(and matching@types/react/@types/react-domwhen using TypeScript). - Whether the task is XYChart, primitive composition, or a specialized layout (geo/hierarchy/network/stats/…).
- Animation peers:
@react-spring/webonly when importingAnimated*from@visx/xychartor@visx/react-spring.
- All
- Refresh package evidence and docs URLs from source-map.md.
- For install strategy, mental model, scales, shapes, curves, glyphs, markers, text, defs (clip/pattern/gradient), and
@visx/vendor, use setup-core.md. - For axes, grids, legends, annotations, threshold bands, and theming/a11y (4.0 XYChart + 4.1 preview), use guides-decoration.md.
- For ParentSize, bounds,
localPoint, drag, brush, zoom, and tooltips/portals, use interaction-layout.md. - For stats, heatmap, hierarchy, network, sankey, chord, geo, voronoi/delaunay, wordcloud, and kernel clarifications, use specialized-viz.md.
- For XYChart series/providers/themes, react-spring, mock-data, and the
@visx/visxumbrella, use xychart-high-level.md. - For v3→v4 migration, decision guide, production/SSR/a11y/perf, and AI authoring traps, use production-migration.md.
Implementation Judgment
- visx is not a batteries-included charting library. Compose SVG: dimensions → scales → marks/guides → interaction. Prefer the smallest
@visx/*set that answers the job. - D3 computes; React owns the DOM. Scales and shape factories produce numbers/path
dstrings; components render SVG. Do not mix d3 selections/enter/exitinto visx mark trees. - Invert continuous y ranges (
[innerHeight, 0]). SVGygrows downward. - Use named package-root imports (
import { Bar } from '@visx/shape'). Never deep-import@visx/*/lib/...under v4exports. - Prefer
@visx/vendor/d3-*(or declare your ownd3-*) over accidental transitive D3 imports. Do not duplicate vendor + bared3-shape/d3-scalewithout intent. - XYChart for standard cartesian line/area/bar/glyph/stack/group with shared tooltip/theme/annotations. Pass
ScaleConfigobjects ({ type: 'band' }), not live d3 scale instances, intoxScale/yScale. - Primitives for polar, geo, hierarchy, network, stats, custom SVG structure, or minimal bundles.
- Prefer
@visx/delaunayover legacy@visx/voronoifor new Voronoi/hit-target work. @visx/networkdoes not run force layout — supplyx/y(e.g. via externald3-force).@visx/kernelis not KDE. Density →@visx/statsbins/ViolinPlotor external KDE +@visx/shape.- Wrap responsive charts in
ParentSize/useParentSize; guardwidth < 10before rendering. Supply fixed sizes in tests/SSR. - Memoize scale configs and expensive layouts against width/height/data. Treat mutable d3 scales carefully across renders.
- Unique SVG
ids for gradients, patterns, markers, clipPaths, and Threshold clips — especially with multiple charts on one page. - Keep decorative chrome (
Grid*,Axis*, backgrounds)aria-hiddenwhen adding chart semantics; use XYChartaccessibilityLabel/ series focus handlers on 4.0.0.
Verification
Prefer the repo's existing checks. For meaningful visx changes, include the relevant subset:
- Package/version check proving aligned
@visx/*@^4and React 18/19 peers (plus@react-spring/webwhenAnimated*is used). - Typecheck for accessors,
ScaleInput, seriesDatum/dataKey, axis/grid props, and tooltip state — no deep-import types. - Deterministic SVG assertions with fixed
width/height(mockResizeObserverwhen ParentSize/tooltip portal is involved). - Interaction tests for tooltip show/hide, brush domain filter, zoom reset, and keyboard focus when those APIs change.
- Visual smoke for theme tokens, stacked/grouped bars, and annotation placement.
- Bundle/import audit when adding umbrella
@visx/visx, animation, geo TopoJSON, or large hierarchy/network demos. - Migration scan for deep imports, React 16/17 peers, missing
nodeRefonwithBoundingRects, andparentRef.currentafteruseParentSize.