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 MyAppStep 2: If you want to create a development build instead of using Expo Go
npx expo install expo-dev-clientAs 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:
touch index.tsxAnd, paste the below code into index.tsx:
// 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-routerStep 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!