airbnb/visx
π― visx | visualization components
Healthy across the board
weakest axisPermissive license, no critical CVEs, actively maintained β safe to depend on.
Has a license, tests, and CI β clean foundation to fork and modify.
Documented and popular β useful reference codebase to read through.
No critical CVEs, sane security posture β runnable as-is.
- βLast commit 3w ago
- β13 active contributors
- βMIT licensed
- βCI configured
- βTests present
- β Concentrated ownership β top contributor handles 51% of recent commits
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the βHealthyβ badge
Paste into your README β live-updates from the latest cached analysis.
[](https://repopilot.app/r/airbnb/visx)Paste at the top of your README.md β renders inline like a shields.io badge.
βΈPreview social card (1200Γ630)
This card auto-renders when someone shares https://repopilot.app/r/airbnb/visx on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: airbnb/visx
Generated by RepoPilot Β· 2026-05-06 Β· Source
Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale β STOP and ask the user to regenerate it before proceeding. - Treat the AI Β· unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/airbnb/visx shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything β but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
Verdict
GO β Healthy across the board
- Last commit 3w ago
- 13 active contributors
- MIT licensed
- CI configured
- Tests present
- β Concentrated ownership β top contributor handles 51% of recent commits
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live airbnb/visx
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale β regenerate it at
repopilot.app/r/airbnb/visx.
What it runs against: a local clone of airbnb/visx β the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in airbnb/visx | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit β€ 51 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of airbnb/visx. If you don't
# have one yet, run these first:
#
# git clone https://github.com/airbnb/visx.git
# cd visx
#
# Then paste this script. Every check is read-only β no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of airbnb/visx and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "airbnb/visx(\\.git)?\\b" \\
&& ok "origin remote is airbnb/visx" \\
|| miss "origin remote is not airbnb/visx (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift β was MIT at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "lerna.json" \\
&& ok "lerna.json" \\
|| miss "missing critical file: lerna.json"
test -f "package.json" \\
&& ok "package.json" \\
|| miss "missing critical file: package.json"
test -f "packages/visx-annotation/src/index.ts" \\
&& ok "packages/visx-annotation/src/index.ts" \\
|| miss "missing critical file: packages/visx-annotation/src/index.ts"
test -f "packages/visx-axis/src/index.ts" \\
&& ok "packages/visx-axis/src/index.ts" \\
|| miss "missing critical file: packages/visx-axis/src/index.ts"
test -f "babel.config.js" \\
&& ok "babel.config.js" \\
|| miss "missing critical file: babel.config.js"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 51 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~21d)"
else
miss "last commit was $days_since_last days ago β artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) β safe to trust"
else
echo "artifact has $fail stale claim(s) β regenerate at https://repopilot.app/r/airbnb/visx"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
TL;DR
visx is a collection of low-level React visualization components that combine D3's computational power with React's declarative DOM updates. It provides reusable building blocks (scales, shapes, axes, annotations) for constructing data visualizations without writing D3 code directlyβdevelopers compose @visx packages like @visx/shape, @visx/scale, @visx/group to build custom charts. Yarn monorepo managed by Lerna with packages/ containing 40+ scoped packages (@visx/*). Each package (e.g., packages/visx-annotation/src/components, packages/visx-scale/src) exports low-level React components and utilities. Root scripts/ handle build, docs generation, and release automation. Demo workspace (@visx/demo) consumes packages for gallery.
Who it's for
React developers and data visualization engineers at companies like Airbnb who need to build custom, interactive charts and dashboards without managing D3 boilerplate; teams that want composable, TypeScript-first visualization components over opinionated charting libraries.
Maturity & risk
Actively maintained and production-ready. The repo shows v4 (React 19 support) in alpha while v3 is stable; strong CI/CD setup with GitHub Actions workflows for PRs and pushes; TypeScript-first codebase with 2M+ LoC; however, note the large surface area of 40+ packages means maintenance complexity is high.
Moderate complexity and surface area risk: monorepo with 40+ packages (@visx/annotation, @visx/shape, @visx/scale, etc.) means breaking changes impact users widely. D3 dependency chain can be heavy. v4 alpha with React 19 suggests migration surface for existing v3 users. Single project from Airbnb (not Linux Foundation) means dependency on Airbnb's continued investment.
Active areas of work
v4 alpha development with React 19 support (install via @next tag); migration guide and changelog recently updated; active CI with pull_request.yml and push.yml workflows; docs generation pipeline (scripts/generateDocs.ts) suggests ongoing documentation work.
Get running
git clone https://github.com/airbnb/visx.git && cd visx && yarn install (requires Node >=22.0.0, Yarn >=4.0.0 per package.json engines). Then yarn dev:demo to start the gallery dev server, or yarn build to compile all packages.
Daily commands: yarn dev:demo (starts dev server for @visx/demo gallery with hot reload); yarn build (runs build:vendor, babel CJS+ESM, type checking); yarn babel:pkg --scope=@visx/shape (to rebuild a single package).
Map of the codebase
lerna.jsonβ Monorepo root configuration defining workspaces and versioning strategy for all visx packages.package.jsonβ Root workspace definition with build scripts, dependencies, and Node/Yarn version requirements that all contributors must respect.packages/visx-annotation/src/index.tsβ Core export barrel file exemplifying visx's component structure and public API surface.packages/visx-axis/src/index.tsβ Primary axis component exports showing how visualization primitives are organized and exposed.babel.config.jsβ Babel transpilation configuration shared across all packages for consistent CJS/ESM output..eslintrc.jsβ Shared ESLint configuration that enforces code quality standards across the entire monorepo.MIGRATION.mdβ Documents breaking changes and upgrade paths between major versions, essential context for feature work.
How to make changes
Add a new axis component
- Create axis variant file (e.g., AxisDiagonal.tsx) in packages/visx-axis/src/axis/ following AxisBottom.tsx pattern (
packages/visx-axis/src/axis/AxisDiagonal.tsx) - Add new orientation constant to packages/visx-axis/src/constants/orientation.ts (
packages/visx-axis/src/constants/orientation.ts) - Implement utility functions for label transform and tick position in packages/visx-axis/src/utils/ (
packages/visx-axis/src/utils/getLabelTransform.ts) - Export new component from packages/visx-axis/src/index.ts (
packages/visx-axis/src/index.ts) - Add test file packages/visx-axis/test/AxisDiagonal.test.tsx with scale and orientation tests (
packages/visx-axis/test/AxisDiagonal.test.tsx)
Add a new annotation subject type
- Create subject component file (e.g., RectSubject.tsx) in packages/visx-annotation/src/components/ (
packages/visx-annotation/src/components/RectSubject.tsx) - Add types to packages/visx-annotation/src/types/index.ts for the new subject configuration (
packages/visx-annotation/src/types/index.ts) - Consume AnnotationContext in the new subject using packages/visx-annotation/src/context/AnnotationContext.tsx (
packages/visx-annotation/src/context/AnnotationContext.tsx) - Export new subject from packages/visx-annotation/src/index.ts (
packages/visx-annotation/src/index.ts) - Add test file packages/visx-annotation/test/RectSubject.test.tsx following CircleSubject.test.tsx pattern (
packages/visx-annotation/test/RectSubject.test.tsx)
Create a new visualization package
- Create new directory packages/visx-mycomponent/ with tsconfig.json and vitest.config.ts following visx-axis structure (
packages/visx-mycomponent/tsconfig.json) - Add package.json to packages/visx-mycomponent/ with version, exports, and @visx dependencies (
packages/visx-mycomponent/package.json) - Create src/index.ts barrel export in packages/visx-mycomponent/src/ (
packages/visx-mycomponent/src/index.ts) - Implement components in packages/visx-mycomponent/src/ following TypeScript and React patterns from existing packages (
packages/visx-mycomponent/src/MyComponent.tsx) - Add test files in packages/visx-mycomponent/test/ with vitest configuration (
packages/visx-mycomponent/test/MyComponent.test.tsx)
Why these technologies
- React + TypeScript β Type-safe component composition with familiar React patterns for library consumers building dashboards and charts.
- d3 (as peer dependency) β Provides battle-tested scale, axis, and geometric calculation primitives; visx wraps them in React components.
- Lerna monorepo β Enables granular package publishing so consumers can install only needed components (e.g., @visx/axis without @visx/annotation).
- Vitest + React Testing Library β Fast unit testing of component behavior in isolation without mocking entire DOM or heavy test frameworks.
- Babel + TypeScript compiler β Dual-target transpilation to both CommonJS (Node.js) and ES modules (modern bundlers) for maximum ecosystem compatibility.
Trade-offs already made
-
Low-level primitives over high-level composed charts
- Why: Gives consumers maximum flexibility to compose custom visualizations vs. locking them into predefined chart types.
- Consequence: Requires more assembly code in consuming applications but prevents vendor lock-in to specific chart types or data structures.
-
Monorepo with separate packages over single large package
- Why: Reduces bundle size for consumers who only need annotations or only axes, and enables independent versioning.
- Consequence: Increased maintenance complexity managing cross-package dependencies, peer versions, and coordinated releases.
-
React Context for annotation coordination over prop drilling or global state
- Why: Eliminates verbose prop passing while keeping component tree explicit and avoiding external state managers.
- Consequence: Context consumers are tightly coupled to annotation package; not reusable in non-React contexts.
-
Pure utility functions for calculations (getLabelTransform, getTickPosition) over embedded logic
- Why: Enables easier testing, composition, and use outside React if needed; improves code clarity.
- Consequence: Requires consumers to understand and correctly apply utility results; no automatic integration.
Non-goals (don't propose these)
- Does not provide out-of-the-box high-level chart components (bar, line, scatter) β only primitives to build them
- Does not manage application state or data fetching β assumes data flows from parent consumer
- Does not provide styling system or theme management β delegates to CSS/Tailwind/CSS-in-JS
- Does not include server-side rendering helpers
Traps & gotchas
- Node >=22.0.0 and Yarn >=4.0.0 required (strict engines in package.json)βnpm won't work, older Node versions will fail silently. 2) ESM/CJS dual build: ESM=true env var triggers separate babel:esm pass; writeEsmPackageJson.js must run after to add package.json type:module. 3) Lerna monorepo: dependencies between @visx packages not auto-symlinked in devβmust run yarn install after changing package.json. 4) v4 alpha has breaking changesβv3 users upgrading to @next tag must follow MIGRATION.md. 5) Gallery (@visx/demo) requires yarn docs:generate before yarn dev:demo or docs won't render.
Architecture
Concepts to learn
- D3 Scales (Linear, Band, Log, etc.) β Visx wraps D3 scales to map data domains to visual ranges (e.g., time to pixel position); understanding scale types is essential for any chart you build with visx
- SVG Coordinate System and Transforms β Visx components emit SVG primitives (Bar, Line, Area) with x/y positioning; you must understand SVG's y-axis-down convention and transform matrices to position marks correctly
- React Context API (Annotation subcomponents) β packages/visx-annotation uses Context (AnnotationContext.tsx) to pass shared state to child annotation components; needed to understand how Annotation, Connector, Label coordinate without prop drilling
- Lerna Monorepo Publishing β visx is 40+ packages published independently; understanding Lerna's versioning, hoisting, and publish workflow is critical for contributing across packages and releasing
- Dual ESM/CJS Output and Package.json exports β Visx builds to both lib/ (CJS) and esm/ with separate package.json files; necessary for tree-shaking and Node/browser compatibility across consumers
- Curve Generators (D3 Curves) β Line and Area components use D3 curve algorithms (linear, monotone, cardinal); picking the right curve impacts visual smoothness and data fidelity
- Data Accessor Pattern (getLetter, getFrequency) β Visx components accept accessor functions (d => d.value) to extract properties from arbitrary data shapes; this decouples components from your data structure
Related repos
d3/d3β The computational engine visx wrapsβvisx handles D3's scale, shape, and math logic, React handles DOM updates and staterecharts/rechartsβ Opinionated React charting library that also wraps D3; visx is lower-level and more composable by design, recharts is batteries-includednivo/nivoβ Comparable low-to-mid-level React visualization library with D3 underpinnings; both solve charting-without-boilerplate, different API surfacesplotly/plotly.jsβ Standalone visualization library; visx is React-native and more lightweight, plotly is library-agnostic and heavierairbnb/visx-galleryβ If it exists separately: would be the live-deployed demo of packages/visx-demo; companion for showcasing visx capabilities
PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add missing unit tests for visx-annotation components
The visx-annotation package has test files for most components (Annotation.test.tsx, CircleSubject.test.tsx, etc.), but the test suite appears incomplete. Given that this is a core visualization package with complex interactive features (EditableAnnotation, context management via AnnotationContext), comprehensive unit tests would improve reliability and prevent regressions. New contributors can add deeper test coverage for edge cases, prop validation, and integration between components.
- [ ] Review existing test files in packages/visx-annotation/test/ to identify gaps in coverage
- [ ] Add tests for AnnotationContext.tsx context provider behavior and edge cases
- [ ] Add integration tests demonstrating how Annotation, Label, Connector, and Subject components work together
- [ ] Add tests for accessibility attributes and keyboard interactions in EditableAnnotation.tsx
- [ ] Ensure all test files follow the visx testing patterns (check other packages for reference)
Add GitHub Actions workflow for visual regression testing
The repo has basic CI workflows (pull_request.yml, push.yml in .github/workflows), but no visual regression testing workflow. For a visualization library like visx, visual regression tests are critical to catch unintended rendering changes. This would involve setting up a workflow that renders the gallery examples and compares snapshots, protecting against subtle visual bugs that unit tests might miss.
- [ ] Review existing workflows in .github/workflows/pull_request.yml and push.yml to understand the CI setup
- [ ] Create a new workflow file .github/workflows/visual-regression.yml that runs on PR events
- [ ] Configure the workflow to build the demo gallery (yarn dev:demo) and capture visual snapshots
- [ ] Integrate with a visual regression tool (e.g., Percy, Chromatic, or pixelmatch-based approach)
- [ ] Document the visual regression testing process in CONTRIBUTING.md
Complete missing test files for visx-axis package and add type coverage
The visx-axis package exists at packages/visx-axis/src/axis/Axis.tsx but the file structure shows no test/ directory listed, unlike visx-annotation. This is a fundamental package for chart axes that likely has complex prop combinations and edge cases. Adding a comprehensive test suite would be high-value, especially since axis components interact with scales and margins in non-obvious ways.
- [ ] Create packages/visx-axis/test/ directory if it doesn't exist
- [ ] Create packages/visx-axis/test/Axis.test.tsx with tests for horizontal/vertical axes
- [ ] Add tests for scale type handling (linear, time, band, etc.) following visx-annotation test patterns
- [ ] Add tests for label rendering, tick formatting, and margin calculations
- [ ] Create packages/visx-axis/vitest.config.ts following the pattern from visx-annotation
- [ ] Ensure tests are included in the main test suite (check package.json test script)
Good first issues
- Add TypeScript tests for packages/visx-annotation/src/components/CircleSubject.tsx and LineSubject.tsx (no visible tests for these subject types). Pattern: examine packages/visx-shape/src/tests for test structure.
- Add JSDoc examples to packages/visx-scale/src/scales/*.ts scale factories (scaleLinear, scaleBand, etc.)βwould improve auto-generated docs. Copy pattern from existing examples in Readme.md usage section.
- Create a simple example in packages/visx-demo/src showing EditableAnnotation from @visx/annotationβReadme mentions Annotation but no demo of editable variant visible in file list.
Top contributors
- @hshoff β 51 commits
- @invalid-email-address β 35 commits
- @darthmaim β 4 commits
- @wildseansy β 1 commits
- @williaster β 1 commits
Recent commits
98f5312β v4.0.0-alpha.11 (invalid-email-address)6bae78dβ docs(migration): note broken alpha.10 and upcoming alpha.11 re-publish (#2000) (hshoff)fd4726bβ v4.0.0-alpha.10 (invalid-email-address)26697c8β docs(readme): modernize README for v4 alpha (#1999) (hshoff)449b5e9β v4.0.0-alpha.9 (invalid-email-address)9240416β fix(release): force-publish all packages during alpha releases (#1998) (hshoff)e38d404β v4.0.0-alpha.8 (invalid-email-address)cba3343β build(f6309d634bf9d5401f54f1c87fc4d6cb73e63b6a): auto-commit package sizes (invalid-email-address)f6309d6β feat(responsive): support custom ref in useParentSize (#1997) (hshoff)da50a0fβ v4.0.0-alpha.7 (invalid-email-address)
Security observations
The visx visualization library demonstrates a generally secure codebase structure with no critical vulnerabilities detected from static analysis. The primary concerns are medium-severity items related to XSS risks in the HtmlLabel component (which requires code review), lack of a security policy document, and restrictive Node.js engine constraints. The project uses modern tooling (TypeScript, linting, testing) which aids security. Recommendations include: (1) audit HtmlLabel.tsx for proper HTML sanitization, (2) establish a SECURITY.md file for responsible disclosure, (3) relax Node.js version constraints to support more LTS releases, (4) implement dependency audit tooling in CI/CD, and (5) review release scripts for credential handling. No hardcoded secrets, SQL injection risks, or Docker misconfigurations were identified in the visible file structure.
- Medium Β· Missing Security Policy β
Repository root. No SECURITY.md file found in the repository root. This makes it difficult for security researchers to report vulnerabilities responsibly. Fix: Create a SECURITY.md file documenting the security policy and responsible disclosure process, following the GitHub security policy format. - Medium Β· Potential XSS Risk in Annotation Components β
packages/visx-annotation/src/components/HtmlLabel.tsx. The HtmlLabel component in visx-annotation may render HTML content. Without proper sanitization verification, this could be vulnerable to XSS attacks if user-controlled data is passed to the component. Fix: Audit HtmlLabel.tsx to ensure all HTML rendering uses safe sanitization methods (e.g., DOMPurify). Avoid dangerouslySetInnerHTML without strict input validation. Document security considerations in component props. - Low Β· Node Engine Constraint May Exclude Security Updates β
package.json - engines field. The package.json specifies 'node': '>=22.0.0', which is very restrictive. This may prevent users from benefiting from security patches in Node.js LTS versions (like v20.x) if vulnerabilities are found. Fix: Consider supporting Node.js LTS versions (e.g., '>=18.0.0' or '>=20.0.0') to allow wider adoption and ensure users can apply security patches across stable releases. - Low Β· Build Script Token Injection Risk β
package.json - build:release script. The 'build:release' script uses TypeScript to execute './scripts/performRelease/index.ts' without visible input validation. If this script handles credentials or API tokens, there's potential for injection. Fix: Review scripts/performRelease/index.ts to ensure all external inputs are validated and sanitized. Use environment variables for secrets, never pass tokens as script arguments. Ensure the script uses secure API authentication methods. - Low Β· Missing Dependency Audit Configuration β
package.json - scripts section. No visible npm audit configuration, yarn audit policy, or SBOM generation in package.json scripts. This makes it harder to track and manage known vulnerabilities in dependencies. Fix: Add audit scripts and consider using tools like 'yarn audit' or 'npm audit' in CI/CD pipelines. Configure yarn workspaces to use lockfile integrity checks. Generate and maintain a Software Bill of Materials (SBOM). - Low Β· Lerna Monorepo Dependency Management β
lerna.json and packages/*/package.json. The repo uses Lerna for monorepo management. While individual packages have .npmrc files, there's potential risk if package versions across the monorepo are not properly coordinated or if internal package references use weak version constraints. Fix: Review lerna.json configuration for security best practices. Ensure internal package dependencies use exact versions or tight ranges (e.g., 1.0.0 or ~1.0.0, not *). Use 'yarn workspaces' integrity checks.
LLM-derived; treat as a starting point, not a security audit.
Where to read next
- Open issues β current backlog
- Recent PRs β what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals β see the live page for receipts. Re-run on a new commit to refresh.