Hubert
13 min
April 15, 2025

How to master Expo Router: basics, best practices, examples and comparisons

Expo Router is a powerful, yet incredibly simple tool for managing navigation in React Native-based mobile and web applications. With it, you can build truly universal apps with a single, consistent routing structure - without unnecessary configuration. If you're looking for a way to make development faster, code tidier and scalability easier, this is where you'll find the answer. This guide will take you step-by-step through Expo Router's capabilities - from the basics to advanced production scenarios.

Read more
How to master Expo Router: basics, best practices, examples and comparisons
Schedule a free consultation

    We process your data in accordance with our privacy policy.

    What is Expo Router?

    Expo Router is a modern way to manage navigation in mobile apps built with Expo and React Native. It allows you to create routes in a style familiar from web frameworks such as Next.js, i.e. using a file structure.

    Instead of manually configuring routes, all you need to do is create the appropriate files and folders in the app/ directory — each of them automatically becomes a page in the application. This approach is similar to routing in web frameworks such as Next.js, and makes it extremely easy to build apps that run simultaneously on Android, iOS, and in a browser. Although it runs on the React Navigation engine, Expo Router removes much of the configuration, offering readability, consistency, and full deep link support with no extra effort.

    How does routing work in Expo Router? Basic concepts

    Expo Router is based on a few fundamental principles that give it simplicity and clarity while allowing you to build advanced navigation structures in multiplatform apps. This approach eliminates the need for manual route configuration and replaces it with a logical mapping of paths using files and folders.

    3.1. File-based routing
    The basic assumption of Expo Router is that each file in the app/ directory corresponds to a single route in the application. The folder structure reflects the URL structure, both on the web and in native applications. This means that the path to the file app/profile/settings.tsx generates the route /profile/settings, without the need to add configuration code. The router also supports dynamic paths and additional configuration files, such as +html.tsx (for HTML configuration), +not-found.tsx (for 404), or bracketed route groups, e.g. (tabs).

    3.2. _layout.tsx = App.tsx
    The _layout.tsx file acts as a global application wrapper — it is responsible for the layout and logic that was previously placed in the App.tsxfile. This is where fonts are loaded, providers (e.g., authorization context) are integrated, and the splash screen is controlled. You can have multiple layouts — separate for different parts of the application — which gives you flexibility without losing clarity.

    Need support with mobile projects?
    Need support with mobile projects?
    Need support with mobile projects?
    Contact us!

    3.3. Deep linking out-of-the-box
    Expo Router generates routes by default that can be used as external links — both in the web and mobile versions. Deep links work without additional routing configuration. Simply specify the URI scheme in the app.jsonfile, and every route in the app will become accessible via its full address, e.g. myapp://profile/settings or https://myapp.com/profile/settings.

    3.4. Component separation
    The app/ folder should only contain routes — files that correspond to screens. The rest of the logic, UI components, hooks, and tools should be kept in separate folders, such as components/hooks/, or utils/. This prevents a regular component from being treated as a route and keeps the code structure clear.

    3.5. Default start route
    Expo Router does not require you to declare a start screen in your code. The first index.tsx file that corresponds to the route /is automatically selected.If If you want the user to start in a different part of the application, you can place the start screen in a route group, e.g. app/(tabs)/index.tsx. Such a folder will not affect the final URL, but will allow you to organize the navigation structure logically.

    3.6. Expo Router works on React Navigation
    Although Expo Router simplifies the way routes are defined, it still works on top of React Navigation. It automatically translates the file structure into stacks, tabs, and modals, which would need to be defined manually in the classic approach. This allows you to take advantage of React Navigation’s full documentation, styling options, and advanced configuration mechanisms.

    Key features of Expo Router

    Expo Router offers a set of features that simplify navigation while giving you a lot of control over the behavior of your app. Although its operation is highly automated, this does not mean that its capabilities are limited — on the contrary, most of the mechanisms you need are available right away, without any additional configuration.

    One of the most important features is built-in deep linking. Each route created in the file structure is automatically available as a URL — both in the mobile version (using URI schemes) and in a browser. This makes it possible to direct the user to a specific screen of the application from a link in a message, browser, or push notification without writing your own link handling logic.

    The router has also been optimized for performance. In production mode, routes are loaded dynamically, i.e., only when needed. In development mode, the Fast Refresh feature available on every platform is used, which significantly speeds up code iteration. Additionally, the Metro bundler built into Expo supports automatic bundle splitting and bundle configuration modification.

    Expo Router integrates seamlessly with native features and libraries. Thanks to autolinking, installing dependencies that run at the native level does not require manual linking or editing project files. Just install the library and restart with install, and Expo will take care of the rest.

    Another important advantage is the universal approach — the same route structure and layouts work independently of the platform. This allows you to create applications that look and behave consistently on Android, iOS, and in the browser. Additionally, Expo Router supports web-specific configuration files such as +html.tsx and +not-found.tsx, allowing you to, for example, use your own HTML start code or handle 404 errors in a web-style.

    Finally, it’s worth mentioning that Router supports the <Link /> and <Stack /> components, allowing you to create navigation using familiar React mechanisms. You can also use dynamic routes, modals, redirects, and custom navigation logic, giving you a lot of freedom — even though most of it works “automatically.”

    In summary, the most important features of Expo Router are:

    – file structure-based routing (app/)
    – automatic deep linking without additional configuration
    – support for dynamic routes, modals, redirects, and 404 errors
    – support for layouts for route groups and global UI (_layout.tsx)
    – lazy loading of routes in production mode
    – fast refresh available on Android, iOS, and the web
    – support for autolinking native libraries
    – full integration with Metro bundler and package splitting
    – universal routing structure that works on any platform
    – compatibility with <Link /> components and other React Navigation mechanisms

    How to get started with Expo Router?

    Getting started with Expo Router is extremely easy, especially if you already have experience with React or Expo. The tool works out of the box and does not require manual configuration or installation of additional libraries. The whole process boils down to a few commands and a few minutes.

    The fastest way to get a project up and running with Expo Router built-in is to use the official template, which includes a ready-made route structure and sample layouts. The recommended choice to start with is the tab-based template, which you can generate with a single command:

    npx create-expo-app@latest --template tabs@50
    

    After creating a project, all you have to do is navigate to its directory and launch the application with the command:

    npx expo start
    

    The generated project contains a directory app/, which contains sample routing files(index.tsx, two.tsx), layout(_layout.tsx) and special files like +html . tsx and +not-found.tsx. This gives you an immediate look at how routing works, the navigation structure and how to manage tab views.

    All navigation logic works right away – without additional configuration or defining stacks. You can immediately add new screens, modify layouts and extend the project according to your needs. This allows Expo Router to let you focus on building the product, not the infrastructure.

    Best practices and folder architecture

    The right project structure is one of the key factors influencing the scalability and maintainability of an application. Although Expo Router gives you a lot of freedom, it’s worth sticking to a few proven rules that help keep things tidy — especially in larger projects.

    The most important thing is to consistently separate navigation logic from the rest of the application code. The app/folder should only contain route files — that is, screens that are rendered in response to a specific URL. Each of these files is a separate page, and their arrangement in folders creates the navigation structure. If you use layouts for tabs, modals, or other interface elements, place them directly in the appropriate route groups.

    All other elements — UI components, hooks, business logic, constants, and tools — should be located outside the app/folder. It is a good idea to organize them into separate directories such as components/hooks/utils/, or services/. This keeps the code clean and easy to test, and eliminates the risk of accidentally treating a component as a route.

    In projects that use the classic src/ division, you can move the entire app/ structure to src/app/. Expo Router supports this layout and treats it the same as the main application folder. This is especially useful if you want to maintain a single entry point for all source code and better separate it from configuration files.

    Example of a practical project structure:

    src/
    ├── app/
    │   ├── _layout.tsx
    │   ├── (auth)/
    │   │   ├── login.tsx
    │   │   └── register.tsx
    │   ├── (tabs)/
    │   │   ├── _layout.tsx
    │   │   ├── index.tsx
    │   │   └── profile.tsx
    │   └── +not-found.tsx
    │
    ├── components/
    │   ├── Button.tsx
    │   └── Header.tsx
    │
    ├── hooks/
    │   └── useAuth.ts
    │
    ├── utils/
    │   └── validators.ts
    │
    └── services/
        └── api.ts
    

    Expo Router vs. React Navigation

    Expo Router and React Navigation are two different approaches to the same goal: managing navigation in React Native apps. Although both tools come from the same ecosystem and are technologically related, they differ in philosophy, ergonomics, and scope of control.

    The main difference lies in how routes are defined. React Navigation relies on a manual approach: you create stacks, tabs, and screens through components configured in code. This approach offers great flexibility and precision but can require a lot of boilerplate, especially in larger projects. Expo Router introduces a file-based approach familiar from the web. Each file in the app/ directory automatically becomes a route, and all navigation is based on the folder hierarchy. In terms of performance, both solutions are very similar — they both use the same low-level navigation components, so the differences in application behavior are practically unnoticeable. However, it is worth noting that Expo Router automates many things, which can significantly speed up the team’s work — especially during the prototyping and MVP development stages.

    When it comes to documentation, community, and available materials, both tools are well documented and have active communities. React Navigation has a slightly larger base, which is due to its longer presence on the market, but Expo Router is quickly catching up thanks to its integration with the entire Expo ecosystem. The choice between these tools depends mainly on the type of project and the team’s preferences. Web developers will appreciate Expo Router for its familiar structure and quick onboarding. Mobile teams that need full control over navigation behavior and use non-standard scenarios may prefer to stick with React Navigation.

    Comparison summary:

    FeatureExpo RouterReact Navigation
    The logic of navigationRouting based on file structureConfiguration of stacks and screens in code
    Web supportBuilt-in, with universal deep linkingSupported, but requires configuration
    FlexibilityLess code, but the structure imposes a certain frameworkMore control and full flexibility
    PerformanceClose to native, lazy loading routesClose to native
    CommunityGrowing, Expo-integratedVery large, broad community support
    Learning curveMore intuitive for web developersMore natural for experienced mobile developers
    Integracja z ExpoTight integration, works right awayMay require additional configuration (e.g., stacks, links, web)

    Potential disadvantages and limitations of Expo Router

    1. Dependency on the Expo ecosystem
    Expo Router only works within the Expo environment. It cannot be used in projects based on pure React Native CLI, which limits its use in more custom or natively configured projects. If you need full control over build configuration, native code, or external CI/CD systems, this dependency may be a barrier. In this case, we invite you to read our article “How to start a project in React Native – Expo or React Native CLI?”

    2. Limited flexibility with complex navigation structures
    File-based routing works great in most cases, but for very complex applications that have unusual screen hierarchies, conditional navigation logic, or non-standard transitions between views, it may require workarounds or additional configuration. What is configured in code in React Navigation must be “fit” into the folder structure here.

    3. Less natural approach for mobile developers
    For developers with experience in native mobile app development who are used to stacks and explicitly configured navigation, Expo Router’s approach may seem too automatic or intrusive. This can increase the learning curve and make it difficult to migrate older projects.

    4. Younger ecosystem and fewer production patterns
    Although Expo Router is growing rapidly, its ecosystem is still younger than that around React Navigation. This means fewer real-world examples, fewer ready-made integrations, fewer templates, and potentially fewer resources for teams with more advanced needs.

    5. Limitations in transition and animation customization
    Compared to manual configuration in React Navigation, Expo Router gives less control over custom animations, transitions between screens, and modal stacks. While you can use React Navigation’s low-level API, this often requires mixing styles, which complicates the code.

    Summary

    Expo Router is one of the most interesting tools to emerge in the React Native ecosystem in recent years. It combines the simplicity of web frameworks with the power and flexibility of native mobile development. With its file-based approach, automatic deep link handling, and native integration with Expo, it significantly reduces the time needed to build an app that runs simultaneously on Android, iOS, and the web.

    This solution is ideal for MVPs and smaller projects as well as scalable enterprise applications — provided that the team accepts tight integration with the Expo ecosystem. Its short learning curve makes it an ideal tool for frontend developers entering the world of mobile apps, but also an attractive alternative for mobile teams looking to speed up development and simplify code management.

    Expo Router does not solve all problems, but it very effectively eliminates the most common ones — unnecessary configuration, repetitive code, and complex navigation handling. If you value consistency, readability, and speed, this tool may be one of the best choices for your next project.

    Frequently asked questions about Expo Router:

    1. Can I use Expo Router outside of the Expo environment?
    No. Expo Router only works in Expo-based projects and is not compatible with pure React Native CLI.

    2. Does Expo Router replace React Navigation?
    Not entirely. Expo Router is built on top of React Navigation and automates its configuration, but it does not exclude its use — you can still use its API.

    3. Do I need to know React Navigation to use Expo Router?
    It is not required, but knowledge of React Navigation can help with more advanced scenarios and navigation customization.

    4. Does Expo Router support web applications?
    Yes. Expo Router supports universal routing that works on Android, iOS, and in a browser (Web).

    5. How does migration from React Navigation to Expo Router work?
    Migration requires reorganizing the project structure (routing to app/), but does not always mean rewriting the logic — many components can be reused.

    Connected articles
    See all
    Discover more topics