Migrating from react-router to wouter

alekseiberezkin

Aleksei Berezkin

Posted on November 29, 2024

Migrating from react-router to wouter

Artwork: https://code-art.pictures/

Why migrate to wouter?

react-router adds about 30 kB (minified) to your bundle, while wouter requires less than 4 kB. Although the react-router team has made significant efforts in version 7 to optimize its bundle size, it still feels excessive if your primary task is simply switching between a few routes.

Moreover, implementing server-side rendering (SSR) with wouter is straightforward. In contrast, with react-router v7, SSR is only easy when you use it as a framework. If you prefer to use it as a library, the process is unclear since it's not documented — an omission that's both surprising and frustrating, to be honest.

Why stay with react-router?

react-router is a mature library with a large and active community. If your project involves complex routing scenarios, react-router is more likely to provide the tools and support you need.

Hint: If you decide to stick with react-router, be sure to upgrade from v6. Version 7 is about twice as efficient in terms of bundle size.

1. Updating deps to wouter

npm uninstall react-router react-router-dom
npm i wouter
Enter fullscreen mode Exit fullscreen mode

If you're already on react-router v7, you probably don't have react-router-dom.

2. Updating Routes to Switch

  • Update imports
  • Change <Routes> to <Switch>
  • In your routes, move elements from element property to <Route>'s children

Before

import { BrowserRouter, Route, Routes } from 'react-router'

function App() {
  return (
    <Routes>
      <Route path='/' element={<Index/>} />
      ...
    </Routes>
  )
}
Enter fullscreen mode Exit fullscreen mode

After

import { Route, Switch } from 'wouter'

function App() {
  return (
    <Switch>
      <Route path='/'>
        <Index/>
      </Route>
      ...
    </Switch>
  )
}
Enter fullscreen mode Exit fullscreen mode

3. Updating Links

Just update imports. wouter has the same API here

Before

import { Link } from 'react-router'
Enter fullscreen mode Exit fullscreen mode

After

import { Link } from 'wouter'
Enter fullscreen mode Exit fullscreen mode

4. Updating navigation

  • Update imports
  • Change useNavigate() to useLocation()
  • Change navigate() to setLocation()

Before

import { useNavigate } from 'react-router'

function MyComponent() {
  const navigate = useNavigate()

  function navToAbout() {
    navigate('/about')
  }

  // ...
}
Enter fullscreen mode Exit fullscreen mode

After

import { useLocation } from 'wouter'

function MyComponent() {
  const [, setLocation] = useLocation()

  function navToAbout() {
    setLocation('/about')
  }

  // ...
}
Enter fullscreen mode Exit fullscreen mode

5. Implementing SSR

I don’t know how to implement SSR with react-router v7 🙂 That’s why, in this step, we’ll implement it from scratch using wouter — it’s surprisingly simple. All you need to do is wrap your app in a <Router> component:

entry-server.js

import { renderToString } from 'react-dom/server'
import { Router } from 'wouter'

function prerenderApp() {
  return renderToString(
    <Router ssrPath='/'>
      <App />
    </Router>
  )
}
Enter fullscreen mode Exit fullscreen mode

entry-client.js

import { hydrateRoot } from 'react-dom/client'
import { Router } from 'wouter'

hydrateRoot(
  document.getElementById('app-root'),
  <Router>
    <App />
  </Router>
)
Enter fullscreen mode Exit fullscreen mode

We are done!

Now run your favorite bundle analyzer (e.g., webpack-bundle-analyzer or vite-bundle-visualizer) and enjoy the results!

💖 💪 🙅 🚩
alekseiberezkin
Aleksei Berezkin

Posted on November 29, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Migrating from react-router to wouter
webdev Migrating from react-router to wouter

November 29, 2024

Is this real?
webdev Is this real?

November 28, 2024

My Github project
webdev My Github project

November 26, 2024