HomeGuidesReferenceLearn

Async routes

Learn how to speed up development with async bundling in Expo Router.


This feature is still experimental. Available from Expo SDK 49 and Expo Router v2.

Expo Router can automatically split your JavaScript bundle based on the route files using React Suspense. This enables faster development as only the routes you navigate to will be bundled or loaded into memory. This can also be useful for reducing the initial bundle size for your application.

Apps using the Hermes Engine will not benefit as much from bundle splitting as the bytecode is already memory mapped ahead of time. However, it will improve your over-the-air updates, React Server Components, and web support.

When bundling for production, all suspense boundaries will be disabled and there will be no loading states.

How it works

All Routes are wrapped inside a suspense boundary and are loaded asynchronously. This means that the first time you navigate to a route, it will take a little longer to load. However, once it is loaded, it will be cached and subsequent visits will be instant.

Loading errors are handled in the parent route, via the ErrorBoundary export.

Async routes cannot be statically filtered during development, so all files will be treated as routes even if they don't export a default component. After the component is bundled and loaded, then any invalid route will use a fallback warning screen. This behavior is development-only and will not be present in production.

Setup

Enable the feature by setting the asyncRoutes option to development in your app config:

app.json
{
  "expo": {
    "plugins": [
      [
        "expo-router",
        {
          "origin": "https://acme.com",
          "asyncRoutes": "development"
        }
      ]
    ]
  }
}

You can set platform-specific settings (default, android, ios or web) for asyncRoutes using an object:

app.json
{
  "expo": {
    "plugins": [
      [
        "expo-router",
        {
          "origin": "https://acme.com",
          "asyncRoutes": {
            "android": false,
            "default": "development"
          }
        }
      ]
    ]
  }
}

Then, when you are about to start your project, you can use the --clear flag to clear the Metro cache. This will ensure that the routes are loaded asynchronously:

Terminal
npx expo start --clear

# Or when exporting
npx expo export --clear

Static rendering

The current static rendering system doesn't support rendering React Suspense boundaries to static HTML, so async routes will be disabled on web when rendering static pages. This will be improved in the future.

  • Ask a question on the forums

  • Edit this page

Was this doc helpful?