Skip to content

React Router v5

Today, we are excited to announce the release of React Router version 5. You can get it using:

$ npm install react-router
# or
$ npm install react-router-dom
# or
$ npm install react-router-native


  • React Router version 5 is now available
  • v5 is fully backwards compatible with 4.x
    • The only reason for the major version bump has to do with how we were specifying dependencies in react-router-dom
  • v5 introduces several structural improvements, including:
    • Better support for React 16
    • Eliminates all warnings in <StrictMode>
    • New context API (internal only)
    • Fully automated releases
  • v5 also introduces a few new features

Structural Improvements

This release is light on features and fixes, and is more focused on stability and compatibility and preparing the library for future releases.

There are no breaking changes in this release. If you are already using version 4.x, you can use version 5 immediately with zero code changes. 🎉 Version 5 will pick up where the 4.x roadmap (now the 5.x roadmap) left off.

The most significant improvement in v5 is better allaround support for React 16, while maintaining full compatibility with React >= 15. We know that a lot of React Router users are maintaing apps they've built over the last few years using various versions of React 15 or 16 and React Router 4, and we are showing our committment to you with this release. This includes upgrading from using React's legacy context API, as well as eliminating all other <StrictMode> warnings. My sincere thanks to Tim Dorr for getting the ball rolling here, and my good friend Jared Palmer for prodding me along.

Using the new context API in React 16 (we use Jamie Kyle's create-react-context shim for backwards compat with React 15) also allows us to avoid the "update blocking" problem that you may have had to work around in the past.

Side note: we have been working on this problem for over 2 years now ... good to see it finally fixed! 😅

Other housekeeping items in this release include a complete overhaul to our bundling infrastructure and full test coverage for all bundles we publish. Before this release we were only running tests on our source code, so there was a chance that our build introduced a bug somewhere. But now all our builds pass all our tests.

We switched from publishing multiple files for each build to a single file in v5, just like React itself (we copied their code! 😉). We also introduced pre-optimized builds for production, so you don't have to manually set process.env.NODE_ENV to production in your build script if you don't want to (though you probably still want to, for other stuff). The point is, you won't be building the router as part of your build. We've already taken care of that, in both development and production modes.

Probably the most significant change here is that instead of requiring individual files from the router, you need to destructure your imports from the main bundle.

// Instead of:
import Router from 'react-router/Router';
import Switch from 'react-router/Switch';

// do:
import { Router, Switch } from 'react-router';

The former style is still supported but will issue a warning in development.

In addition to these improvements, we did some work to streamline and automate the release process, so we should be able to release more frequently and predictably from now on.

New Features

One of the main new features in this release is the ability to use an array in <Route path>, so if you want to render the same component at 2 different route paths, you no longer have to create 2 routes.

// Instead of this:
  <Route path="/users/:id" component={User} />
  <Route path="/profile/:id" component={User} />

// you can now do this:
<Route path={["/users/:id", "/profile/:id"]} component={User} />

There are also a few fixes in this release, including support for React.createRef in <Link innerRef> and support for using React.forwardRef in <Route component>.

Why the major version bump?

We originally intended to release React Router version 5 as 4.4, which we actually did last Friday. However, there was one major consequence which we didn't foresee, and it all boils down to a single character: ^.

We have always tried to do versioning as closely as possible to the way the React team does versioning for their packages. In version 4, we have been releasing all react-router* packages in lock step. This means that when you install e.g. react-router-dom version 4.3.0, it depends on react-router version 4.3.0. This makes it easy for people to know which version of each package they need, and is the same as react-dom and react do.

However, there's one subtle difference between react-router-dom and react-dom, which is that react-router-dom includes react-router as a dependency, not a peer dependency. So in react-router-dom version 4.3.1 we have a dependency on "react-router": "^4.3.1" (note the ^).

At the time we released version 4.4 of both packages on Friday, we had been beta testing 4.4 for over 5 months. We had received tons of feedback over the course of 8 separate beta releases and squashed quite a few bugs, so we felt pretty confident that everything was ready for 4.4 final. But there was one case that we hadn't considered, which is that technically react-router-dom version 4.3.x could depend on react-router version 4.4, which they can't because of the changes to how we're using our internal context API. So although there were no public API breakages between 4.3.x and 4.4.0, there was a chance that some people could install 2 mismatched versions. What made this even trickier is that nobody noticed this bug until 4.4 was out of beta, because there was no chance you'd get a 4.4 beta installed alonside react-router-dom 4.3.x.

In the end, we decided that the fix that would cause the least pain for everyone would be to npm unpublish version 4.4.0 and re-release it as 5.0.0. This means that:

  • Anyone using version 4.3.x will not get the version mismatch and
  • people who want the new stable version (5.0.0) are still able to get it.

We apologize for any pain this caused. To fix this problem going forward, we are pinning the react-router dependency in each version of react-router-dom so there is no chance of a version mismatch. We may have a better solution for this in the future, but that's the safest thing for now.


This release was made possible by many contributors including Tim Dorr, Paul Sherman, Bogdan Chadkin, Dan Levy, Brandon John Lewis, Benjamin Atkin, Hongbo Miao, Ches Zhuravsky, Benjamin Johnson, Daniel Powell, Vernon de Goede, Sebastian Silbermann, Mateusz Burzyński, Ben Mason, Kevin Vicrey, Anthony Frehner, Saugat Acharya, Rick Hanlon II, Eugene Dzhumak, Tien Pham, Peter Fu, alireza-mh, gcangussu, JBallin, misacorn, and many others who contributed code, wrote documentation, or helped us during the beta testing phase.

I'm sure I missed a few names, so if you helped out and I missed you, please let me know!



While we don't have blog comments, we tweeted about this posting when it went live so we welcome your comments there:

React Router

Michael Jackson and Ryan Florence create the React libraries that you use in your apps like React Router and Reach UI. All of our trainers are experts in React and JavaScript so let us share our knowledge with you and your team!

I Love React
© React Training 2019