React 19 Upgrade Guide
April 25, 2024 by Ricky Hanlon
The improvements added to React 19 require some breaking changes, but we’ve worked to make the upgrade as smooth as possible, and we don’t expect the changes to impact most apps.
In this post, we will guide you through the steps for upgrading to React 19:
If you’d like to help us test React 19, follow the steps in this upgrade guide and report any issues you encounter. For a list of new features added to React 19, see the React 19 release post.
Installing
To install the latest version of React and React DOM:
npm install --save-exact react@^19.0.0 react-dom@^19.0.0Or, if you’re using Yarn:
yarn add --exact react@^19.0.0 react-dom@^19.0.0If you’re using TypeScript, you also need to update the types.
npm install --save-exact @types/react@^19.0.0 @types/react-dom@^19.0.0Or, if you’re using Yarn:
yarn add --exact @types/react@^19.0.0 @types/react-dom@^19.0.0We’re also including a codemod for the most common replacements. See TypeScript changes below.
Codemods
To help with the upgrade, we’ve worked with the team at codemod.com to publish codemods that will automatically update your code to many of the new APIs and patterns in React 19.
All codemods are available in the react-codemod repo and the Codemod team have joined in helping maintain the codemods. To run these codemods, we recommend using the codemod command instead of the react-codemod because it runs faster, handles more complex code migrations, and provides better support for TypeScript.
Changes that include a codemod include the command below.
For a list of all available codemods, see the react-codemod repo.
Breaking changes
Errors in render are not re-thrown
In previous versions of React, errors thrown during render were caught and rethrown. In DEV, we would also log to console.error, resulting in duplicate error logs.
In React 19, we’ve improved how errors are handled to reduce duplication by not re-throwing:
- Uncaught Errors: Errors that are not caught by an Error Boundary are reported to
window.reportError. - Caught Errors: Errors that are caught by an Error Boundary are reported to
console.error.
This change should not impact most apps, but if your production error reporting relies on errors being re-thrown, you may need to update your error handling. To support this, we’ve added new methods to createRoot and hydrateRoot for custom error handling:
const root = createRoot(container, {
onUncaughtError: (error, errorInfo) => {
// ... log error report
},
onCaughtError: (error, errorInfo) => {
// ... log error report
}
});For more info, see the docs for createRoot and hydrateRoot.
Removed deprecated React APIs
Removed: propTypes and defaultProps for functions
PropTypes were deprecated in April 2017 (v15.5.0).
In React 19, we’re removing the propType checks from the React package, and using them will be silently ignored. If you’re using propTypes, we recommend migrating to TypeScript or another type-checking solution.
We’re also removing defaultProps from function components in place of ES6 default parameters. Class components will continue to support defaultProps since there is no ES6 alternative.
// Before
import PropTypes from 'prop-types';
function Heading({text}) {
return <h1>{text}</h1>;
}
Heading.propTypes = {
text: PropTypes.string,
};
Heading.defaultProps = {
text: 'Hello, world!',
};// After
interface Props {
text?: string;
}
function Heading({text = 'Hello, world!'}: Props) {
return <h1>{text}</h1>;
}Removed: Legacy Context using contextTypes and getChildContext
Legacy Context was deprecated in October 2018 (v16.6.0).
Legacy Context was only available in class components using the APIs contextTypes and getChildContext, and was replaced with contextType due to subtle bugs that were easy to miss. In React 19, we’re removing Legacy Context to make React slightly smaller and faster.
If you’re still using Legacy Context in class components, you’ll need to migrate to the new contextType API: