React 19
Upgrading from React 16 to 19 will be a huge task, and will more or less affect every single file in MapStore. The most difficult task will be, to make sure that all the react libraries are still compatible. Some of them will need to be replaced or updated, and the code around it will need to be rewritten as a result.
Here are some of the tasks that needs to be done
- Upgrade to react 19
- Follow the react 17, 18, 19 upgrade guides and make changes according to their breaking changes list
- Update libraries to a version that supports react 19
- Replace the libraries that doesn't support react 19
- Remove recompose
- Rewrite test
React 17 breaking changes we are affected by
React 18 breaking changes we are affected by
React 19 breaking changes we are affected by
React 19 is the upgrade that brings in the most changes, and also breaks a lot of our dependencies. For our own code they provided several codemods that we can make use of, see their upgrade guide for more info.
- React 19 upgrade guide - https://react.dev/blog/2024/04/25/react-19-upgrade-guide
- New JSX Transform is now required
- Removed: Legacy Context using contextTypes and getChildContext
- Removed: propTypes and defaultProps for functions
- Removed: react-dom/test-utils - Used in 312 files
- Removed: ReactDOM.render
- Removed: unmountComponentAtNode
- Removed ReactDOM.findDOMNode
What about test
- Replace 1000+ usages of ReactDOM.render with ReactDOM.createRoot
- Replace 407 usages of ReactDOM.findDOMNode
- Replace 708 usages of ReactDOM.unmountComponentAtNode
- React 17 changed how event delegation is done, this will break some of our tests
- React-dom/test-utils will be removed, this code can probably be replaced with @testing-library/react
- The
act function should be imported from react instead of react-dom/test-utils
- We will need to rewrite our test, as we rewrite our code, but that is to be expected.
React-bootstrap
It might work with React 19? But probably needs heavy testing. Even if it does work, we should consider upgrading to the latest version sometime in the future
- We are using react-bootstrap 0.31.0 from 2017-04-26
- Upgrading react-bootstrap will require us to upgrade bootstrap, see https://github.com/react-bootstrap/react-bootstrap
- React-bootstrap 2 requires react 16.14.0+
- React-bootstrap v3 beta requires react 18.3.1+
React-redux
Our current version of react-redux is 9 years old, but it might work with React 19. I however think we should update, and now would be the perfect timing..
- We are using react-redux 6.0.0 which was released 5th december 2018
- We are using redux 3.6.0
- react-redux 7+ ( Requires react 16.8.4 )
- react-redux 9+ ( Requires react 18 )
- The connect function is being deprecated with react-redux 9.3.0 see https://github.com/reduxjs/react-redux/releases/tag/v9.3.0
- React-redux 9 now requires Redux Core 5, but they strongly encourage that we switch to RTK ( Redux Toolkit 2.0 )
Connect
´The connect function is officially being deprecated in v9.3.0, they recommend using useSelector and useDispatch hooks instead. See https://redux.js.org/usage/migrating-to-modern-redux#modernizing-react-components-with-react-redux
While it is not strictly necessary to remove connect right now, it would make sense to remove it while we are removing recompose anyways. Removing connect would make the code cleaner, more modern and in my opinion easier to read. We are using connect ~427 places across ~266 files. .
Redux libs
React libs
In a perfect world we should update every package to the latest version,. but that would be a major task, and very time consuming. I think we should handle the packages in the following order:
- Replace the packages where the current and the latest version doesn't work with React 19
- Update the packages where the current version doesn't support react 19
- Replace the package that are either deprecated on npm or archived in github
- Update the package that gives peer dependency warnings on install
- Update the rest of the packages
Some packages will work without updating them, but will most likely require that we keep legacy-peer-deps=true in the .npmrc file
React libs that needs to be replaced
The following packages doesn't work with react 19
- react-quill
- connected-react-router
- react-notification-system
- react-container-dimensions
- We could make our own component
- react-widgets
- Looking at the issues in their github project, it seems that React 19 is not supported very well
- We are using DateTimePicker, Combobox, MultiSelect, Calendar, DropdownList
React libs that must be updated
The following npm packages must be updated to work with react 19
- react-draggable
- react-checkbox-tree
- react-intl
- react-grid-layout
- react-share
- react-pdf
- react-resize-detector
- react-select
- react-router
Deprecated or archived packages
The foolowing packages are either deprecated on npm or archived in github. This means they will no longer receive updates, security fixes and they might become incompatible with react in the future.
- prop-types
- react-sidebar
- react-nouislider
- react-overlays
- react-image-lightbox
Packages we might be able to update before upgrading to React 19
- react-draggable
- react-checkbox-tree
- react-grid-layout
- react-select
- react-pdf
Packages that might work anyways
- qrcode.react
- prop-types
- react-swipeable
- react-string-replace
- react-copy-to-clipboard
- react-dropzone
- react-contenteditable
- react-overlays
- react-color
- react-spinkit
React libs table
The "supports react 19" columns should be taken with a grain of salt, especially the one regarding the current version. This information is based off changelogs, github issues, their reported peerDependencies, or a quick test I have done in a minimal react 19 app.
| Package |
Current version |
Latest version |
Release date |
Latest release date |
Current Supports R19? |
Latest Supports R19 |
Current peer dependency |
Latest peer dependency |
Deprecated |
Note |
| react-draggable |
2.2.6 |
4.6.0 |
2017-04-30 |
2026-05-29 |
No |
Yes |
|
>= 16.3.0 |
No |
|
| react-checkbox-tree |
1.5.1 |
2.0.2 |
2019-01-28 |
2026-05-28 |
No |
Yes |
^15.3.0 || ^16.0.0 |
^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 |
No |
|
| react-intl |
2.3.0 |
10.1.11 |
2017-05-09 |
2026-05-27 |
No |
Yes |
^0.14.9 || ^15.0.0 |
19 |
No |
|
| react-error-boundary |
1.2.5 |
6.1.2 |
2019-03-29 |
2026-05-25 |
Yes |
Yes |
^16.0.0-beta.1 |
^18.0.0 || ^19.0.0 |
No |
|
| react-redux |
6.0.0 |
9.3.0 |
2018-12-05 |
2026-05-15 |
Yes |
Yes |
^16.4.0-0 |
^18.0 || ^19 |
No |
|
| react-grid-layout |
1.2.0 |
2.2.3 |
2020-11-17 |
2026-03-24 |
No |
Yes |
|
>= 16.3.0 |
No |
|
| react-share |
1.15.1 |
5.3.0 |
2017-06-18 |
2026-03-09 |
No |
Yes |
0.13.x || 0.14.x || 15.x.x |
^17 || ^18 || ^19 |
No |
|
| react-pdf |
7.7.3 |
10.4.1 |
2024-05-07 |
2026-02-25 |
No |
Yes |
^16.8.0 || ^17.0.0 || ^18.0.0 |
^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 |
No |
|
| react-intersection-observer |
8.24.1 |
10.0.3 |
2019-07-15 |
2026-02-18 |
Yes |
Yes |
^15.0.0 || ^16.0.0 || ^17.0.0 |
^17.0.0 || ^18.0.0 || ^19.0.0 |
No |
|
| react-player |
1.15.3 |
3.4.0 |
2020-05-26 |
2025-11-13 |
Yes* |
Yes |
* |
^17.0.2 || ^18 || ^19 |
No |
Current version seems to work, but spams the console with warnings. The latest version increased from ~9 dependencies to 50 dependencies, and the size went up from less than 1mb to 190mb |
| react-resize-detector |
4.2.1 |
12.3.0 |
2019-09-18 |
2025-08-27 |
No |
Yes |
^16.0.0 |
^18.0.0 || ^19.0.0 |
No |
|
| react-select |
1.3.0 |
5.10.2 |
2018-07-23 |
2025-07-11 |
No |
Yes |
^0.14.9 || ^15.3.0 || ^16.0.0-rc || ^16.0 |
^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 |
No |
|
| qrcode.react |
0.9.3 |
4.2.0 |
2019-02-17 |
2024-12-11 |
Yes |
Yes |
^15.5.3 || ^16.0.0 |
^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 |
No |
|
| prop-types |
15.7.2 |
15.8.1 |
2019-02-13 |
2022-01-05 |
Yes |
Yes |
|
|
Archived |
Replace with typescript? |
| react-swipeable |
5.5.1 |
7.0.2 |
2020-02-08 |
|
Yes |
Yes |
^16.0.0-0 |
^16.8.3 || ^17 || ^18 || ^19.0.0 || ^19.0.0-rc |
No |
|
| react-quill |
1.1.0 |
2.0.0 |
2017-08-04 |
2022-08-03 |
No |
No |
^0.14.9 || ^15.3.0 || ^16.0.0 |
^16 || ^17 || ^18 |
No |
Look for alternative ( react-quill-new ) |
| connected-react-router |
6.3.2 |
6.9.3 |
2019-03-10 |
2022-07-11 |
No |
No |
^16.4.0 |
^16.4.0 || ^17.0.0 |
No |
Has a beta |
| react-notification-system |
0.2.14 |
0.4.0 |
2017-05-03 |
2020-05-06 |
No |
No |
0.14.x || ^15.0.0 |
0.14.x || ^15.0.0 || ^16.0.0 |
No |
Maybe react-toastify |
| react-container-dimensions |
1.4.1 |
1.4.1 |
2018-08-14 |
2018-08-14 |
No |
No |
^0.14.0 || ^15.0.0 || 16.x |
^0.14.0 || ^15.0.0 || 16.x |
No |
Doesn't work due to the removal of findDOMNode |
| react-sidebar |
2.3.2 |
3.0.2 |
2017-04-22 |
2018-08-08 |
Yes |
Yes |
>=0.14.0 |
>=16.4.2 |
Archived |
|
| react-nouislider |
2.0.1 |
2.0.1 |
2017-08-27 |
2017-08-27 |
Yes |
Yes |
^0.14.0 || ^15.0.1 || ^16.0.0 |
^0.14.0 || ^15.0.1 || ^16.0.0 |
Deprecated |
|
| react-string-replace |
1.1.0 |
2.0.1 |
2022-05-02 |
2026-11-01 |
Yes |
Yes |
|
|
No |
|
| react-router |
4.1.1 |
7.16.0 |
|
2026-05-28 |
No |
Yes |
^15 |
>=18 |
No |
|
| react-copy-to-clipboard |
5.0.0 |
5.1.1 |
2017-04-26 |
2026-03-07 |
Yes |
Yes |
^15.3.0 |
>=15.3.0 |
No |
Works, but update to solve peerDependency error |
| react-dropzone |
3.13.1 |
15.0.0 |
2017-04-26 |
2026-02-10 |
No |
Yes |
^0.14.0 || ^15.0.0 |
>=16.8 || 18.0.0 |
No |
|
| @testing-library/react |
12.1.5 |
|
|
2026-01-19 |
|
|
<18.0.0 |
|
No |
|
| react-codemirror2 |
4.0.0 |
9.0.1 |
2018-01-29 |
2025-10-24 |
? |
? |
>=15.5 <=16.x |
>=15.5 <=19.x |
No |
|
| react-dock |
0.2.4 |
0.8.0 |
2017-04-22 |
2025-03-01 |
Yes |
Yes* |
>=0.13.0 |
^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 |
No |
Latest versions works, but shows error in console |
| react-widgets |
3.5.0 |
5.8.6 |
2017-09-06 |
2025-02-01 |
No |
No |
^0.14.0 || ^15.0.0 |
>=0.16.0 |
No |
Might have issues with React 19 |
| react-contenteditable |
3.3.2 |
3.3.7 |
2019-08-18 |
2023-02-28 |
Yes |
Yes |
>=16.3 |
>=16.3 |
No |
|
| react-scroll-up |
1.3.7 |
1.4.0 |
2020-11-29 |
2022-12-16 |
Yes |
Yes |
0.13 - 17 |
0.13 - 18 |
No |
|
| react-overlays |
1.2.0 |
5.2.1 |
2019-03-07 |
2022-09-16 |
Yes |
Yes |
>=16.3.0 |
>=16.3.0 |
Archived |
Deprecated - Consider using react-dom createPortal |
| react-plotly.js |
2.6.0 |
2.6.0 |
2022-09-08 |
2022-09-08 |
Yes |
Yes |
>0.13.0 |
>0.13.0 |
No |
|
| react-dnd |
2.6.0 |
16.0.1 |
2018-03-21 |
2022-04-19 |
No |
|
* |
>=16.14 |
No |
|
| react-dnd-html5-backend |
2.6.0 |
16.0.1 |
2018-03-21 |
2022-04-19 |
- |
|
|
|
No |
|
| react-dnd-test-backend |
2.6.0 |
16.0.1 |
2018-03-21 |
2022-04-19 |
- |
|
|
|
No |
|
| react-image-lightbox |
4.2.2 |
5.1.4 |
2017-10-05 |
2021-07-14 |
No |
- |
^15.5.0 |
16.x || 17.x |
Deprecated |
|
| react-textfit |
1.1.0 |
1.1.1 |
2017-11-17 |
2020-12-11 |
Yes |
Yes |
^15.0.0 || ^16.0.0 |
^15.0.0 || ^16.0.0 |
No |
|
| react-color |
2.17.0 |
2.19.3 |
2018-12-21 |
2020-10-28 |
Yes |
Yes |
* |
|
No |
|
| recompose |
0.24.0 |
0.30.0 |
2017-07-12 |
2018-08-30 |
- |
- |
^0.14.0 || ^15.0.0 |
^0.14.0 || ^15.0.0 || ^16.0.0 |
Archived |
No longer recommended |
| react-spinkit |
2.1.2 |
3.0.0 |
2017-05-01 |
2017-05-22 |
Yes |
Yes |
|
|
No |
v3 requires process to be exposed to the browser |
| react-data-grid |
5.0.4 |
? |
2018-11-14 |
|
No |
|
^15.0.0 || ^16.0.0 |
^19.2 |
No |
|
| react-swipeable-views |
0.12.2 |
0.14.1 |
2017-05-13 |
|
No |
|
^15.0.0 || ^0.14.0 |
^15.3.0 || ^16.0.0 || ^17.0.0 |
No |
|
| @geosolutions/react-joyride |
1.10.2 |
|
|
|
No |
- |
|
|
? |
The latest version supports react-19 |
| @geosolutions/react-draft-wysiwyg |
1.14.8 |
|
|
|
- |
- |
|
|
? |
|
| react-data-grid-addons |
5.0.4 |
6.1.0 |
|
|
- |
|
^16.8 |
|
No |
Has beta |
| @babel/preset-react |
7.27.1 |
|
|
|
Yes |
Yes |
|
|
No |
|
| react-bootstrap |
0.31.0 |
2.10.10 |
|
|
Yes |
|
|
|
No |
Has a 3.0 beta |
| eslint-plugin-react |
3.16.1 |
|
|
|
|
|
|
|
|
Update or consider switching to @eslint-react/eslint-plugin |
Recompose
Recompose should be replaced with hooks
| Name |
Usage |
Files |
Replaced with |
| compose |
364 |
259 |
|
| import 'recompose' |
344 |
|
|
| require recompose |
3 |
|
|
| import "recompose" |
17 |
|
|
| {compose} |
5 |
5 |
|
| { compose } |
31 |
31 |
|
| createSink |
281 |
71 |
useEffect |
| withProps |
121 |
88 |
Regular props |
| withHandlers |
92 |
83 |
useCallback |
| defaultProps |
88 |
81 |
regular props |
| withPropsOnChange |
80 |
40 |
useMemo |
| withState |
61 |
37 |
useState |
| branch |
56 |
46 |
if-statement - conditional rendering |
| mapPropsStream |
51 |
33 |
|
| getContext |
38 |
20 |
useContext |
| withStateHandlers |
33 |
33 |
useState |
| setObservableConfig |
26 |
26 |
|
| createEventHandler |
24 |
16 |
|
| withContext |
20 |
4 |
createContext(null) |
| lifecycle |
16 |
15 |
useEffect |
| shouldUpdate |
2 |
2 |
memo |
| pure |
1 |
1 |
memo |
Other considerations
- Rewrite class components to use functions. Class components are considered a legacy API by React. We are using React.Component in ~271 files
- Implement typescript.
- Recommended replacement for prop-types
- Great timing to start implementing typescript, as we will be rewriting a lot of the code anyways
- Type safety, makes for fewer mistakes in code
- RTK 2.0 heavily benefits from using typescript
- Makes it easier for downstream projects to use components
React 19
Upgrading from React 16 to 19 will be a huge task, and will more or less affect every single file in MapStore. The most difficult task will be, to make sure that all the react libraries are still compatible. Some of them will need to be replaced or updated, and the code around it will need to be rewritten as a result.
Here are some of the tasks that needs to be done
React 17 breaking changes we are affected by
React 18 breaking changes we are affected by
React 19 breaking changes we are affected by
React 19 is the upgrade that brings in the most changes, and also breaks a lot of our dependencies. For our own code they provided several codemods that we can make use of, see their upgrade guide for more info.
What about test
actfunction should be imported from react instead of react-dom/test-utilsReact-bootstrap
It might work with React 19? But probably needs heavy testing. Even if it does work, we should consider upgrading to the latest version sometime in the future
React-redux
Our current version of react-redux is 9 years old, but it might work with React 19. I however think we should update, and now would be the perfect timing..
Connect
´The connect function is officially being deprecated in v9.3.0, they recommend using useSelector and useDispatch hooks instead. See https://redux.js.org/usage/migrating-to-modern-redux#modernizing-react-components-with-react-redux
While it is not strictly necessary to remove connect right now, it would make sense to remove it while we are removing recompose anyways. Removing connect would make the code cleaner, more modern and in my opinion easier to read. We are using connect ~427 places across ~266 files. .
Redux libs
React libs
In a perfect world we should update every package to the latest version,. but that would be a major task, and very time consuming. I think we should handle the packages in the following order:
Some packages will work without updating them, but will most likely require that we keep
legacy-peer-deps=truein the .npmrc fileReact libs that needs to be replaced
The following packages doesn't work with react 19
React libs that must be updated
The following npm packages must be updated to work with react 19
Deprecated or archived packages
The foolowing packages are either deprecated on npm or archived in github. This means they will no longer receive updates, security fixes and they might become incompatible with react in the future.
Packages we might be able to update before upgrading to React 19
Packages that might work anyways
React libs table
The "supports react 19" columns should be taken with a grain of salt, especially the one regarding the current version. This information is based off changelogs, github issues, their reported peerDependencies, or a quick test I have done in a minimal react 19 app.
Recompose
Recompose should be replaced with hooks
Other considerations