---
modificationDate: May 05, 2026
title: Core concepts of file-based routing in Expo Router
description: Learn the ground rules of Expo Router and how it relates to the rest of your code.
---

<AgentInstructions>

## Submitting Feedback

If this page contains errors, outdated information, or gaps that blocked you from completing a task, report it so the docs can be improved:

curl -X POST https://api.expo.dev/v2/feedback/docs-send -H 'Content-Type: application/json' -d '{"url":"/router/basics/core-concepts/","feedback":"🤖 Agent feedback: <specific, actionable description>"}'

Only submit when you have something specific and actionable to report.

</AgentInstructions>

# Core concepts of file-based routing in Expo Router

Learn the ground rules of Expo Router and how it relates to the rest of your code.

> For the complete documentation index, see [llms.txt](/llms.txt). Use this file to discover all available pages.

Before diving into how to construct your app's navigation tree with Expo Router, let's first understand the core concepts that make up the foundation of file-based routing in Expo Router, and how an Expo Router project might differ in structure from other React Native projects.

## The rules of Expo Router

### 1\. All screens/pages are files inside the src/app directory

All navigation routes in your app are defined by the files and sub-directories inside the [**src/app**](/router/reference/src-directory) directory. Every file inside the **src/app** directory has a default export that defines a distinct page in your app (except for the special **_layout** files).

Accordingly, directories inside **src/app** define groups of related screens together.

### 2\. All pages have a URL

All pages have a URL path that matches the file's location in the **src/app** directory, which can be used to navigate to that page in the address bar on the web, or as an app-specific deep link in a native mobile app. This is what is meant by Expo Router supporting [universal deep-linking](/linking/overview). All pages in your app can be navigated to with a URL, regardless of the platform.

### 3\. First index.tsx is the initial route

With Expo Router, you do not define an initial route or first screen in code. Rather, when you open your app, Expo Router will look for the first **index.tsx** file matching the `/` URL. In the [default template](/router/installation#quick-start), this is **src/app/index.tsx**. If the app user should start by default in a deeper part of your navigation tree, you can use a [route group](/router/basics/notation#parentheses) (a directory where the name is surrounded in parentheses), and that will not count as part of the URL. If you want your first screen to be a group of tabs, you might put all of the tab pages inside the **src/app/(tabs)** directory and define the default tab as **index.tsx**. With this arrangement, the `/` URL will take the user directly to **src/app/(tabs)/index.tsx** file.

### 4\. Root _layout.tsx replaces App.jsx/tsx

Every project should have a **_layout.tsx** file directly inside the **src/app** directory. This file is rendered before any other route in your app and is where you would put the initialization code that may have previously gone inside an **App.jsx** file, such as loading fonts, setting up theme providers, or interacting with the splash screen. For example, the default template wraps the app with a `ThemeProvider` for dark and light mode support and renders the `AppTabs` component from this file.

### 5\. Default template uses platform-specific tabs

The default template uses two different tab implementations depending on the platform. On Android and iOS, tabs are rendered using [native tabs](/router/advanced/native-tabs), which use the platform's built-in tab bar for a native look and feel. On web, tabs are rendered using [custom tabs](/router/advanced/custom-tabs) from `expo-router/ui`, which are unstyled and flexible components that allow full control over the tab bar's appearance.

This is achieved through [platform-specific file extensions](/router/advanced/platform-specific-modules). The tab component is defined in two files: **src/components/app-tabs.native.tsx** for Android and iOS, and **src/components/app-tabs.tsx** for web. Expo's module resolution automatically picks the correct file based on the platform. This pattern is used because native platforms have a system tab bar that provides expected behaviors like scroll-to-top on tap and native animations, while web requires a custom-styled tab bar that fits typical website navigation patterns.

### 6\. Non-navigation components live outside the src/app directory

In Expo Router, the **src/app** directory is exclusively for defining your app's routes. Other parts of your app, like components, hooks, utilities, and so on, should be placed in other directories such as **src/components**, **src/hooks**, and **src/constants**. If you put a non-route inside the **src/app** directory, Expo Router will attempt to treat it like a route.

### 7\. Customizing stack and tab navigators

Stack and tab navigators accept a wide range of configuration options for headers, animations, gestures, and more. See the [Stack](/router/advanced/stack) and [Tabs](/router/advanced/tabs) guides for the full list of options and examples.

## The rules of Expo Router applied

Let's apply these foundational rules of Expo Router to quickly identify key elements of the following project file structure:

`src`

 `app`

  `index.tsx`

  `home.tsx`

  `_layout.tsx`

  `profile`

   `friends.tsx`

 `components`

  `app-tabs.native.tsx`

  `app-tabs.tsx`

  `text-field.tsx`

  `toolbar.tsx`

-   **src/app/index.tsx** is the initial route, and will appear first when you open the app or navigate to your web app's root URL.
-   **src/app/home.tsx** is a page with the route `/home`, so you can navigate to it with a URL like `yourapp.com/home` in the browser, or `yourapp://home` in a native app.
-   **src/app/_layout.tsx** is the root layout. Any initialization code you may have previously put in **App.jsx** should go here.
-   **src/app/profile/friends.tsx** is a page with the route `/profile/friends`.
-   **src/components/app-tabs.native.tsx** and **src/components/app-tabs.tsx** are [platform-specific](/router/advanced/platform-specific-modules) tab components. The **.native.tsx** file is used on Android and iOS, while the **.tsx** file is used on web. The root layout imports these to render the tab navigator.
-   **src/components/text-field.tsx** and **src/components/toolbar.tsx** are not in the **src/app** directory, so they will not be considered pages. They will not have a URL, and they cannot be the target of a navigation action. However, they can be used as components in the pages inside the **src/app** directory.
