Safeguard
Open Source

React 18.3: The Safe Stepping Stone to React 19

React 18.3 is functionally identical to 18.2 but adds deprecation warnings for React 19. Upgrading through it is a security move as much as a compatibility one.

Karan Patel
Platform Engineer
5 min read

React 18.3 is an intentionally boring release: it is functionally identical to React 18.2.0 but adds warnings for APIs that are deprecated or changing in React 19, and stepping through it is the recommended way to surface migration problems before they become production incidents. From a security standpoint, staying on a maintained, current React line is the whole point — an app pinned to an old minor is an app that stops receiving fixes, and 18.3 is the low-risk bridge that keeps you moving forward.

The React team was explicit about this design. Rather than bundle behavior changes into 18.3, they shipped a version that runs your existing 18.2 app exactly as before while lighting up console warnings for everything React 19 will remove or alter. You get a free static-analysis pass on your own codebase.

Why "identical plus warnings" is the right idea

Most upgrade pain comes from combining a runtime behavior change with an API removal in one jump. React 18.3 deliberately separates those. Because the runtime matches 18.2, upgrading from react 18.2 to 18.3 should not change how your app behaves. What changes is your console: deprecated patterns light up as warnings, giving you a punch list to work through before you take the 19 jump. Treat those warnings as a to-do list, not noise.

npm install react@18.3 react-dom@18.3
# then run your app and your test suite, and read the console

Run this in a branch, exercise the app, and collect every warning. Common ones involve legacy string refs, deprecated lifecycle methods, and defaultProps on function components. Fix them while you are still on 18.x, where the fix is low-risk, rather than while also absorbing React 19's runtime changes.

The security case for not lagging

There is a real security dimension to version currency. React and react-dom get fixes over time, and the broader ecosystem — routers, form libraries, testing tools — drops support for old React minors. An app frozen on react 18.2.0 slowly accumulates dependencies you cannot safely upgrade because their new versions require a newer React. That coupling is how projects get stuck on a vulnerable transitive package: the fix exists, but taking it demands a React bump you have been avoiding. Moving through 18.3 keeps that door open.

Testing: the enzyme adapter question

The upgrade often stalls on test tooling, and Enzyme is the usual culprit. The official Enzyme project never shipped a React 18 adapter; the API changes in React 18 would have required a substantial rework of Enzyme and its adapter utilities that the maintainers did not undertake. What exists is a community-maintained enzyme-adapter-react-18 package (published outside the official Enzyme org) that provides React 18 support.

If you depend on it, two things follow. First, verify its provenance and maintenance status like any community fork — check the repository, the maintainer, and the release cadence before you pin it. Second, recognize that riding an unofficial adapter is technical debt that will make the React 19 move harder. The React team recommends React Testing Library as the supported path forward, and migrating your tests off enzyme-adapter-react-18 and onto Testing Library is worth scheduling as part of the same modernization effort.

# If you must stay on Enzyme for React 18 in the interim
npm ls enzyme enzyme-adapter-react-18 react
# Preferred direction: migrate tests to @testing-library/react

A pragmatic upgrade order

  1. Upgrade to react@18.3 and react-dom@18.3 in a branch.
  2. Run the app and full test suite; capture every deprecation warning.
  3. Resolve warnings on the 18.x line, where behavior is unchanged.
  4. Sort out test tooling — ideally migrate off the enzyme-adapter-react-18 community adapter toward Testing Library.
  5. Only then plan the React 19 jump, now with a clean console.

This sequence keeps each step small and reversible, which is exactly what you want when the goal is to stay current without a risky big-bang migration. Audit your dependency tree at each step with npm audit and an SCA scan so you catch any advisory that the version churn exposes.

FAQ

Is React 18.3 different from React 18.2?

Functionally, no. React 18.3 is identical to 18.2 at runtime. The only additions are warnings for APIs that are deprecated or changing in React 19, which makes it a safe intermediate step before upgrading to 19.

Why upgrade to React 18.3 at all?

To collect React 19 deprecation warnings while your app still behaves exactly like 18.2, so you can fix them in a low-risk environment. Staying current also keeps the rest of your dependency tree upgradeable, which matters for patching vulnerabilities.

Does Enzyme work with React 18?

Not via an official adapter — the Enzyme project never shipped one. A community-maintained enzyme-adapter-react-18 package exists, but the recommended long-term path is migrating tests to React Testing Library.

Should I skip 18.3 and go straight to React 19?

You can, but it combines an API removal with runtime changes in one jump. Stepping through 18.3 first lets you clear deprecation warnings while behavior is unchanged, which makes the React 19 migration much safer.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.