Skip to content

React 19 Support#1968

Merged
hshoff merged 17 commits intomasterfrom
hshoff-react19
Nov 10, 2025
Merged

React 19 Support#1968
hshoff merged 17 commits intomasterfrom
hshoff-react19

Conversation

@hshoff
Copy link
Member

@hshoff hshoff commented Nov 10, 2025

This PR adds React 19 support to visx with automatic JSX transform and improves module resolution across all packages.

💥 Breaking Changes

  • React 19 support with automatic JSX transform - All packages now support React 16.14+, 17, 18, and 19 using automatic JSX runtime. Manual React imports have been removed from component files across all packages.
  • Dropped IE 11 support - Modernized Babel configuration to target modern browsers (Chrome 108+, Edge 108+, Firefox 133+, Safari 15.6+). IE 11 and other legacy browsers are no longer supported.
  • Standardized React peerDependencies - All packages now require React ^16.14.0 || ^17.0.0-0 || ^18.0.0-0 || ^19.0.0-0 (previously varied between ^16.0.0-0, ^16.3.0-0, and ^16.8.0-0). This ensures consistent minimum version requirements across all visx packages.
  • Dropped support for React < 16.14 - React versions below 16.14.0 are no longer supported. Users on React 16.0-16.13 must upgrade to React 16.14 or later.

🚀 Enhancements

  • Package exports field - Added exports field to all package.json files for better ESM/CJS module resolution and tree-shaking support
  • Explicit type exports - All packages now export types explicitly, enabling better TypeScript tooling and autocomplete. Migrated to package root imports (e.g., import { Foo } from '@visx/shape' instead of import Foo from '@visx/shape/lib/shapes/Foo')
  • Demo upgraded to React 19 and Next.js 15 - Demo application updated with latest React 19, Next.js 15, and simplified configuration
  • @react-spring/web v10 - Upgraded react-spring dependency to v10 for better React 19 compatibility
  • Standardized react-dom peerDependencies - Packages requiring react-dom now consistently specify ^16.14.0 || ^17.0.0-0 || ^18.0.0-0 || ^19.0.0-0

🐛 Bug Fix

  • Fixed React 19 key prop warnings - Resolved React 19 warnings by avoiding spread of key prop in Tooltip component and test files
  • Type safety improvements - Fixed type issues in demo sandboxes with proper package imports

🏠 Internal

  • Modern build configuration - Updated Babel config with stricter transpilation (loose: false) and React preset optimizations (useBuiltIns, useSpread)
  • ESLint configuration - Added TypeScript type/value separation rules to enforce consistent import patterns
  • Demo improvements - Replaced deep imports with package root imports across all demo sandboxes and improved type definitions
  • Test updates - Fixed React 19 compatibility warnings in xychart test suite

Note: This PR maintains backward compatibility with React 16.14+ while adding full support for React 19. No API changes are required for existing users, though updating bundler configurations to leverage the new exports field is recommended for optimal tree-shaking.

IE 11 and legacy browser support has been dropped in favor of modern browser targets. If you still need to support IE 11:

  • Use the previous version of visx (before this release)
  • Or configure your build tool to transpile node_modules/@visx/* packages with your own Babel/TypeScript configuration targeting IE 11

Closes

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds comprehensive React 19 support to the visx library while maintaining backward compatibility with React 16.14+. The changes enable automatic JSX runtime transformation, standardize module exports across all packages, and update the demo application to React 19 and Next.js 15.

Key changes:

  • Removed manual React imports from component files across all packages (leveraging automatic JSX transform)
  • Added exports field to all package.json files for improved ESM/CJS resolution and tree-shaking
  • Standardized React peerDependencies to ^16.14.0 || ^17.0.0-0 || ^18.0.0-0 || ^19.0.0-0 across all packages

Reviewed Changes

Copilot reviewed 299 out of 311 changed files in this pull request and generated no comments.

Show a summary per file
File Description
packages/visx-xychart/test/components/AreaStack.test.tsx Fixed React 19 key prop warnings by using inline string literals instead of spreading key from object
packages/visx-xychart/test/components/AreaSeries.test.tsx Updated test to avoid spreading key prop and use inline string literals
packages/visx-xychart/src/components/Tooltip.tsx Refactored to prevent key prop spreading in React 19
packages/visx-xychart/src/utils/*.ts Migrated from deep imports to package root imports
packages/visx-xychart/package.json Added exports field and updated React/react-spring peerDependencies
packages/*/src/index.ts Added explicit type exports using export type * pattern
packages/*/package.json Added exports field and standardized React peerDependency version
packages/visx-demo/* Updated demo sandboxes to use package root imports instead of deep imports
babel.config.js Enabled automatic JSX runtime
.eslintrc.js Disabled react-in-jsx-scope rule for automatic JSX transform

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@github-actions
Copy link

github-actions bot commented Nov 10, 2025

Size Changes

Package Diff ESM Prev ESM CJS Prev CJS
visx-annotation 🔻 -31.3% 19.16 KB 27.89 KB 23.2 KB 35.64 KB
visx-axis 🔻 -35.6% 13.03 KB 20.22 KB 17.71 KB 24.53 KB
visx-bounds 🔻 -44.6% 1.44 KB 2.6 KB 1.87 KB 3.06 KB
visx-brush 🔻 -20.7% 41 KB 51.67 KB 42.97 KB 54.29 KB
visx-chord 🔻 -29.2% 1.84 KB 2.6 KB 2.62 KB 3.29 KB
visx-clip-path 🔻 -56.2% 1.45 KB 3.31 KB 2.65 KB 4.31 KB
visx-delaunay 🔻 -37.2% 1.41 KB 2.25 KB 2.43 KB 2.96 KB
visx-drag 🔻 -26.9% 8.83 KB 12.08 KB 10.77 KB 13.54 KB
visx-event -7.4% 3.45 KB 3.73 KB 5.13 KB 4.97 KB
visx-geo 🔻 -35.4% 7.86 KB 12.16 KB 11.4 KB 15.05 KB
visx-glyph 🔻 -41.4% 7.01 KB 11.97 KB 11.15 KB 15.41 KB
visx-gradient 🔻 -55.8% 6.69 KB 15.13 KB 11.31 KB 19.03 KB
visx-grid 🔻 -42.6% 9.35 KB 16.29 KB 12.59 KB 19.39 KB
visx-group 🔻 -61.3% 484 B 1.22 KB 1.01 KB 1.64 KB
visx-heatmap 🔻 -45.7% 3.39 KB 6.25 KB 4.46 KB 7.11 KB
visx-hierarchy 🔻 -15.2% 8.42 KB 9.92 KB 13.14 KB 14.31 KB
visx-legend 🔻 -38.2% 14.44 KB 23.36 KB 20.27 KB 28.47 KB
visx-marker 🔻 -51.4% 3.72 KB 7.65 KB 5.98 KB 9.45 KB
visx-mock-data -0.1% 317.99 KB 318.39 KB 322.98 KB 321.62 KB
visx-network 🔻 -26.3% 2.97 KB 4.03 KB 4.99 KB 5.77 KB
visx-pattern 🔻 -20.0% 7.16 KB 8.95 KB 10.08 KB 11.35 KB
visx-point 🔻 -24.1% 761 B 1003 B 1.86 KB 1.74 KB
visx-react-spring 🔻 -33.9% 8.47 KB 12.81 KB 10.75 KB 15.76 KB
visx-responsive 🔻 -41.6% 8.81 KB 15.08 KB 11.24 KB 17.03 KB
visx-sankey 🔻 -24.3% 2.42 KB 3.2 KB 3.8 KB 4.06 KB
visx-scale -2.1% 18.36 KB 18.75 KB 30.19 KB 29.38 KB
visx-shape 🔻 -37.2% 50.58 KB 80.48 KB 72.87 KB 100.37 KB
visx-stats 🔻 -28.3% 9.02 KB 12.58 KB 10.44 KB 13.66 KB
visx-text 🔻 -28.5% 5.8 KB 8.11 KB 7.28 KB 9.58 KB
visx-threshold 🔻 -14.3% 2 KB 2.33 KB 2.69 KB 2.88 KB
visx-tooltip 🔻 -34.3% 8.94 KB 13.61 KB 13.35 KB 18.01 KB
visx-voronoi 🔻 -36.4% 1.25 KB 1.97 KB 2.04 KB 2.56 KB
visx-wordcloud 🔻 -18.8% 1.92 KB 2.37 KB 2.92 KB 3.12 KB
visx-xychart 🔻 -27.1% 122.16 KB 167.56 KB 151.95 KB 211.48 KB
visx-zoom 🔻 -22.0% 12.19 KB 15.63 KB 14.49 KB 17.85 KB

Compared to master. File sizes are unminified and ungzipped.

View raw build stats

Previous (master)

{
  "visx-annotation": {
    "esm": 28559,
    "lib": 36491
  },
  "visx-axis": {
    "esm": 20709,
    "lib": 25119
  },
  "visx-bounds": {
    "esm": 2662,
    "lib": 3136
  },
  "visx-brush": {
    "esm": 52910,
    "lib": 55596
  },
  "visx-chord": {
    "esm": 2663,
    "lib": 3373
  },
  "visx-clip-path": {
    "esm": 3394,
    "lib": 4415
  },
  "visx-curve": {
    "esm": 336,
    "lib": 1475
  },
  "visx-delaunay": {
    "esm": 2305,
    "lib": 3035
  },
  "visx-demo": {
    "esm": 0,
    "lib": 0
  },
  "visx-drag": {
    "esm": 12368,
    "lib": 13865
  },
  "visx-event": {
    "esm": 3815,
    "lib": 5091
  },
  "visx-geo": {
    "esm": 12450,
    "lib": 15408
  },
  "visx-glyph": {
    "esm": 12256,
    "lib": 15780
  },
  "visx-gradient": {
    "esm": 15496,
    "lib": 19482
  },
  "visx-grid": {
    "esm": 16678,
    "lib": 19853
  },
  "visx-group": {
    "esm": 1251,
    "lib": 1681
  },
  "visx-heatmap": {
    "esm": 6399,
    "lib": 7278
  },
  "visx-hierarchy": {
    "esm": 10161,
    "lib": 14656
  },
  "visx-legend": {
    "esm": 23920,
    "lib": 29153
  },
  "visx-marker": {
    "esm": 7834,
    "lib": 9673
  },
  "visx-mock-data": {
    "esm": 326036,
    "lib": 329336
  },
  "visx-network": {
    "esm": 4124,
    "lib": 5913
  },
  "visx-pattern": {
    "esm": 9161,
    "lib": 11621
  },
  "visx-point": {
    "esm": 1003,
    "lib": 1781
  },
  "visx-react-spring": {
    "esm": 13119,
    "lib": 16134
  },
  "visx-responsive": {
    "esm": 15447,
    "lib": 17439
  },
  "visx-sankey": {
    "esm": 3278,
    "lib": 4160
  },
  "visx-scale": {
    "esm": 19205,
    "lib": 30085
  },
  "visx-shape": {
    "esm": 82414,
    "lib": 102780
  },
  "visx-stats": {
    "esm": 12881,
    "lib": 13990
  },
  "visx-text": {
    "esm": 8309,
    "lib": 9806
  },
  "visx-threshold": {
    "esm": 2386,
    "lib": 2946
  },
  "visx-tooltip": {
    "esm": 13934,
    "lib": 18441
  },
  "visx-vendor": {
    "esm": 2974,
    "lib": 3226
  },
  "visx-visx": {
    "esm": 1524,
    "lib": 3989
  },
  "visx-voronoi": {
    "esm": 2013,
    "lib": 2621
  },
  "visx-wordcloud": {
    "esm": 2423,
    "lib": 3192
  },
  "visx-xychart": {
    "esm": 171585,
    "lib": 216557
  },
  "visx-zoom": {
    "esm": 16001,
    "lib": 18276
  }
}

Current

{
  "visx-annotation": {
    "esm": 19623,
    "lib": 23755
  },
  "visx-axis": {
    "esm": 13345,
    "lib": 18132
  },
  "visx-bounds": {
    "esm": 1476,
    "lib": 1915
  },
  "visx-brush": {
    "esm": 41979,
    "lib": 44001
  },
  "visx-chord": {
    "esm": 1886,
    "lib": 2683
  },
  "visx-clip-path": {
    "esm": 1488,
    "lib": 2713
  },
  "visx-curve": {
    "esm": 336,
    "lib": 2594
  },
  "visx-delaunay": {
    "esm": 1448,
    "lib": 2489
  },
  "visx-demo": {
    "esm": 0,
    "lib": 0
  },
  "visx-drag": {
    "esm": 9039,
    "lib": 11025
  },
  "visx-event": {
    "esm": 3533,
    "lib": 5257
  },
  "visx-geo": {
    "esm": 8044,
    "lib": 11674
  },
  "visx-glyph": {
    "esm": 7177,
    "lib": 11421
  },
  "visx-gradient": {
    "esm": 6854,
    "lib": 11581
  },
  "visx-grid": {
    "esm": 9578,
    "lib": 12892
  },
  "visx-group": {
    "esm": 484,
    "lib": 1030
  },
  "visx-heatmap": {
    "esm": 3473,
    "lib": 4564
  },
  "visx-hierarchy": {
    "esm": 8620,
    "lib": 13458
  },
  "visx-legend": {
    "esm": 14783,
    "lib": 20754
  },
  "visx-marker": {
    "esm": 3806,
    "lib": 6120
  },
  "visx-mock-data": {
    "esm": 325619,
    "lib": 330728
  },
  "visx-network": {
    "esm": 3041,
    "lib": 5105
  },
  "visx-pattern": {
    "esm": 7332,
    "lib": 10317
  },
  "visx-point": {
    "esm": 761,
    "lib": 1901
  },
  "visx-react-spring": {
    "esm": 8675,
    "lib": 11009
  },
  "visx-responsive": {
    "esm": 9021,
    "lib": 11514
  },
  "visx-sankey": {
    "esm": 2482,
    "lib": 3894
  },
  "visx-scale": {
    "esm": 18804,
    "lib": 30918
  },
  "visx-shape": {
    "esm": 51794,
    "lib": 74614
  },
  "visx-stats": {
    "esm": 9234,
    "lib": 10690
  },
  "visx-text": {
    "esm": 5939,
    "lib": 7453
  },
  "visx-threshold": {
    "esm": 2045,
    "lib": 2758
  },
  "visx-tooltip": {
    "esm": 9156,
    "lib": 13672
  },
  "visx-vendor": {
    "esm": 2974,
    "lib": 3226
  },
  "visx-visx": {
    "esm": 1524,
    "lib": 3999
  },
  "visx-voronoi": {
    "esm": 1281,
    "lib": 2088
  },
  "visx-wordcloud": {
    "esm": 1968,
    "lib": 2995
  },
  "visx-xychart": {
    "esm": 125096,
    "lib": 155595
  },
  "visx-zoom": {
    "esm": 12485,
    "lib": 14835
  }
}

- Removed IE 11 from targets
- Added specific modern browser versions (Chrome 108+, Firefox 133+, Safari 15.6+, etc.)
- Changed loose: false for stricter transpilation
- Added useBuiltIns and useSpread optimizations to React preset
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 299 out of 396 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@hshoff hshoff merged commit ed15215 into master Nov 10, 2025
1 check passed
@github-actions
Copy link

🎉 This PR is included in version v4.0.0-alpha.0 of the packages modified 🎉

Copy link

@dsmith3197 dsmith3197 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@hshoff hshoff mentioned this pull request Nov 10, 2025
@hshoff hshoff deleted the hshoff-react19 branch November 10, 2025 21:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Please add support for @react-spring/web 10.x React 19 support Consistent export of types (e.g. ZoomState)

3 participants