Manage Expo Go development workflow for React Native apps. Use when the user mentions Expo Go, starting development server, QR code scanning, testing on physical devices, network issues, running the app on mobile, Expo Router, file-based routing, navigation, tabs, deep linking, or URL schemes.
This skill helps manage Expo Go development workflow for React Native/Expo projects. Expo Go is a sandbox app for rapid mobile development without native build tools.
Note: This project uses bun as the default package manager. Use bunx instead of npx and bun run instead of npm run.
# Standard start (LAN mode - recommended for same network)
bunx expo start
# Tunnel mode (when LAN doesn't work)
bunx expo start --tunnel
# Clear cache and start fresh
bunx expo start --clear
# Specify port
bunx expo start --port 8081
# Start with specific connection type
bunx expo start --lan # LAN mode (default)
bunx expo start --localhost # Local only
bunx expo start --tunnel # Ngrok tunnel
When the dev server is running, use these keyboard shortcuts:
| Key | Action |
|---|---|
a | Open on Android device/emulator |
i | Open on iOS simulator (Mac only) |
w | Open in web browser |
r | Reload app |
m | Toggle menu |
j | Open debugger |
o | Open project code |
c | Show QR code |
? | Show all commands |
@expo/ngrok (auto-installed)This project uses Expo Router for file-based routing. See EXPO-ROUTER.md for complete documentation.
File Conventions:
| File | Purpose |
|---|---|
index.tsx | Default route for directory |
[param].tsx | Dynamic segment |
[...rest].tsx | Catch-all route |
_layout.tsx | Layout wrapper |
(group)/ | Route group (no URL segment) |
Navigation:
import { Link, useRouter } from 'expo-router'
// Declarative
<Link href="/settings">Settings</Link>
// Imperative
const router = useRouter()
router.push('/settings')
router.replace('/home')
router.back()
Reading Params:
import { useLocalSearchParams } from 'expo-router'
const { id } = useLocalSearchParams<{ id: string }>()
This Project's Structure:
app/
├── _layout.tsx # Root layout with TamaguiProvider
├── (tabs)/
│ ├── _layout.tsx # Tab navigator
│ ├── index.tsx # Home tab (/)
│ └── settings.tsx # Settings (/settings)
└── +not-found.tsx # 404 page
This project uses the scheme mattystack defined in app.json:
{
"expo": {
"scheme": "mattystack"
}
}
| Platform | Format |
|---|---|
| iOS/Android | mattystack://path |
| Web | https://yoursite.com/path |
| Expo Go | exp://192.168.x.x:8081/--/path |
# iOS Simulator
xcrun simctl openurl booted "mattystack://settings"
# Android Emulator
adb shell am start -W -a android.intent.action.VIEW -d "mattystack://settings"
# Expo Go (development)
# Use the exp:// URL shown in terminal with /--/path appended
This project is optimized for Replit development with special environment configuration.
Use EXPO_PUBLIC_ prefix for client-accessible variables:
# .env
EXPO_PUBLIC_API_URL=https://api.example.com
EXPO_PUBLIC_ENV=development
Access in code:
const apiUrl = process.env.EXPO_PUBLIC_API_URL
# Start with Replit-optimized configuration
bun run expo:dev
# This runs expo with proper host binding for Replit's network
Replit runs in a container environment. Key considerations:
Use Tunnel Mode: LAN mode won't work from external devices
bunx expo start --tunnel
Webview URL: Access the web version via Replit's webview URL
Environment Variables: Set in Replit Secrets, not .env files in production
# Install EAS CLI
bun add -g eas-cli
# Configure project
eas build:configure
# Create development build
eas build --profile development --platform ios
eas build --profile development --platform android
For detailed troubleshooting steps, see TROUBLESHOOTING.md.
QR Code Won't Scan:
"Network request failed" / Can't Connect:
bunx expo start --tunnelApp Not Updating:
r in terminalbunx expo start --clearExpo Go is a sandbox environment with pre-bundled native modules. You cannot:
react-native-firebase)All expo-* packages work in Expo Go. Check compatibility:
bunx expo install --check
For libraries requiring native code, you must switch to a development build.
Set public environment variables in your app config:
// app.json
{
"expo": {
"extra": {
"apiUrl": "https://api.example.com"
}
}
}
Or use .env files with EXPO_PUBLIC_ prefix:
EXPO_PUBLIC_API_URL=https://api.example.com
Access in code:
const apiUrl = process.env.EXPO_PUBLIC_API_URL;
This project uses bun as the package manager. Check package.json for:
# Development server with custom configuration
bun run expo:dev
# Standard expo start
bunx expo start
bunx expo start --clearCurrent project SDK: Check app.json → expo.sdkVersion
Expo Go supports the latest SDK and one previous version. If your SDK is older, you must either:
bunx expo install expo@latest# Check Expo CLI version
bunx expo --version
# Login to Expo account
bunx expo login
# Check current user
bunx expo whoami
# Install compatible package versions
bunx expo install [package-name]
# Check for dependency issues
bunx expo doctor
# View project config
bunx expo config
# Clear all caches
bunx expo start --clear
watchman watch-del-all # If using watchman
rm -rf node_modules/.cache