React Router’s Future

With React Router 1.0 shipping in November, and 2.0 just around the corner, we wanted to take a moment to talk briefly about the history of the project, but more importantly, the future.


Our API churned a lot leading up to 1.0, that’s because @mjackson and I
have been learning React with everybody else! After just an hour with
React, I immediately began on the Router. I showed Michael this 72-liner, and then the two of us got to work.

API churn is awful, especially when its in a library that’s at the heart of your application. We want React Router to be a stable dependency that’s easy to keep current. Here’s our plan:

  1. 2.0 is fully backward compatible with 1.0 so you can upgrade, and then update your code incrementally.
  2. All deprecated API warns and links to an upgrade guide.
  3. 3.0 will remove 1.0 deprecations completely.
  4. 3.0 will be released no sooner than three months after 2.0. This gives an API, in the worst case scenario, six months of life if you’re staying perfectly up-to-date.
  5. Some codemods that will automatically update your code will be available at rackt/rackt-codemod
If it’s fully backwards compatible, why isn’t that a minor release?

If we didn’t provide the backwards compatibility then you wouldn’t be asking this question — but then upgrading would break your app. We don’t want to break your app, we want smooth, incremental upgrades.

In practice, this means you can:

  1. Upgrade from 1.0 to 2.0 and your app will still run.
  2. Update your code incrementally to the new API, and you have three months before the next release to do it.
  3. Run the codemods to make some of (2) automatic.

We’ll continue this for every major release.

What the Router Can Do Now

Over the last year, our users have brought us various use-cases and we’ve learned a lot about React. We realized that we needed to fundamentally change the way the Router was implemented. With some help from others, Michael took on the rewrite full-time for a few months when not conducting one of our trainings. Many thanks to Modus Create for sponsoring a couple weeks of that work.

Code Splitting

Imagine you’re adding new routes to a photo viewer deep inside your app. You work in a code-base with 100 other developers. Pre 1.0, you would have to:

  1. Edit a route config at the root of the project, and probably cause git conflicts with other teams messing around in there too.
  2. Increase the size of the initial bundle sent to the user.

Pre 1.0, React Router required your entire route config to be defined up front, including which components to render. You could make some components fetch more code at those routes if you wanted, but you still needed the entire route config declared. If you’re a large app, just defining routes is still too many kilobytes.

The initial bundle sent to a user shouldn’t increase just because the number of screens in your app increased.

1.0 brings with it first-class support for code-splitting on routes so that adding routes deep in your app doesn’t increase the size of the initial bundle. You can read more about it here.

Integration With Other Libraries

React Router 1.0 and 2.0 have much cleaner integration points for libraries like Relay, Redux, etc. and its the primary motivation for the 2.0 release.

There’s so much more we’d like to talk about here but should instead focus our effort on talking about it in the docs. Which reminds me …


We’ve focused mostly on the code recently so the docs are pretty rough— especially if you’re trying to learn how to connect all the pieces together.

Coming soon:

  1. 30–60 minute tutorial that takes you from absolute beginner to server rendering and code-splitting a real-life app.
  2. videos for that tutorial.
  3. Updated API docs that are (hopefully) better.

It’s been an difficult but rewarding journey getting here. We think the Router is a solid dependency for every React application. Thanks for your continued support and a shout out to Jimmy Jia, Mateusz Zatorski, Tim Dorr, and Dan Abramov for their help with the project.