- Create a
pnpm
workspace with a subdirectory containing an Expo app - Follow the manual setup directions for
expo-router
- Follow the directions for setting up a monorepo in the Expo documentation
- Modify the Metro config:
// metro.config.js: const path = require("path"); const { getDefaultConfig } = require("expo/metro-config"); const projectRoot = __dirname; const workspaceRoot = path.resolve(__dirname, "../.."); const config = getDefaultConfig(projectRoot); config.watchFolders = [workspaceRoot], config.resolver.nodeModulesPaths = [ path.resolve(projectRoot, "node_modules"), path.resolve(workspaceRoot, "node_modules"), ] module.exports = config;
- Prepend the
run
command withEXPO_USE_METRO_WORKSPACE_ROOT=1
as described in Change the default entrypoint// package.json: { /* ... */ "scripts": { "ios": "EXPO_USE_METRO_WORKSPACE_ROOT=1 expo run:ios", "android": "EXPO_USE_METRO_WORKSPACE_ROOT=1 expo run:android", } /* ... */ }
- Add
node-linker=hoisted
to.npmrc
at the root of the monorepo as described in Can I use another Monorepo tool?# .npmrc: node-linker=hoisted
- Modify the Metro config:
- Install
expo-dev-client
in the Expo appcd apps/expo pnpm i expo-dev-client
- run
pnpm i
in the monorepo root - run either
pnpm ios
orpnpm android
to create and launch a development build - Open the debugger and observe the error
- Click any of the links in the error message to see the resolution error
Source-maps (and by extension, the debugger) should just work.
The debugger gets a 404 error when trying to load the source-map.
Recalling a fix for an older bug, I was able to work around the issue as follows:
- Create an
index.ts
file in the app's root directory (orindex.js
, etc) - Add the following single line:
import "expo-router/entry";
- Update package.json#main to point to the new file
{ "main": "index.ts", /* ... */ }