Navigation is a core part of any mobile app. Expo Router supports file-based routing, inspired by Next.js.
React Navigation, on the other hand, gives you more control and flexibility especially if you are used to the createStackNavigator
pattern.
In this post, I will show how to set up navigation in an Expo project without using Expo Router, including manual app registration with registerRootComponent
.
Why skip Expo Router?
Expo Router is great for quick prototypes, but it might not be the best fit if:
- You prefer explicit navigation over file-based routing.
- Your team already uses React Navigation elsewhere.
- You need more control over screen transitions, nesting, or deep linking.
If any of that sounds like you, let’s follow the steps below.
Step 1: Initialize an Expo Project
First, create a new Expo app:
npx create-expo-app MyApp
cd MyApp
Step 2: If you want to create a development build instead of using Expo Go
npx expo install expo-dev-client
As per the documentation, development build is the term that we use for a "Debug" build of an app that includes the expo-dev-client library.
Step 3: Remove the app/ Directory
Delete the app/
folder created by Expo Router:
rm -rf app/
Step 4: Create a Custom Entry File
Create a new index.tsx
in your project root:
// index.tsx
import { registerRootComponent } from "expo";
import App from "./src/App";
registerRootComponent(App);
Update your package.json
to point to your custom entry file:
// In package.json
{
"name": "my-app",
"main": "./index.tsx"
}
Then create a new src
folder in your project root and define your own App.tsx
in it:
// App.tsx
import React from "react";
import { Text, View } from "react-native";
export default function App() {
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text>Hello World</Text>
</View>
);
}
Step 5: Remove Expo Router from Dependencies
Uninstall expo-router
:
yarn remove expo-router
# or
npm uninstall expo-router
Step 6: Clean Up tsconfig.json
Remove .expo/types/**/*.ts
As this is only used by Expo Router.
Before:
"include": [
"**/*.ts",
"**/*.tsx",
".expo/types/**/*.ts",
"expo-env.d.ts"
]
After:
"include": [
"**/*.ts",
"**/*.tsx",
"expo-env.d.ts"
]
Step 7: Clean Up app.json
Remove expo-router
from plugins:
"expo": {
"plugins": ["expo-router"]
}
Remove typedRoutes
as it is used by Expo Router:
"experiments": {
"typedRoutes": true
}
You now have a clean Expo project without Expo Router, ready for manual navigation setup using libraries like react-navigation
.
Happy coding!