Expo로 개발할 때 자주 쓰는 실행 명령어 모음

Expo 앱을 개발하다 보면 명령어보다 “지금 다시 빌드해야 하나?”가 더 헷갈립니다. 화면 코드만 바꿨는데 Gradle 빌드를 다시 돌리기도 하고, 반대로 스플래시 이미지를 바꾼 뒤 Metro만 재시작해서 왜 그대로인지 한참 보기도 합니다.

이 글은 macOS와 Expo SDK 56을 기준으로, Android와 iOS에서 자주 쓰는 실행 명령을 상황별로 모았습니다.

Expo Go, 개발 빌드, Release 빌드부터 구분하기

실행 방식 | 이럴 때 사용 | 대표 명령
Expo Go | JavaScript·TypeScript 화면을 빠르게 확인할 때 | npx expo start --go
개발 빌드 | 네이티브 모듈, 권한, 앱 설정을 포함해 개발할 때 | npx expo run:android, npx expo run:ios
로컬 Release 빌드 | 스플래시, 최적화, 업데이트 동작을 실제 앱에 가깝게 확인할 때 | Android --variant release, iOS --configuration Release

Expo Go는 빠르지만 앱의 네이티브 설정을 전부 재현하지는 않습니다. 특히 스플래시 화면은 Expo Go나 개발 빌드에서 최종 앱과 다르게 보일 수 있어서 Release 빌드 확인이 필요합니다.

평소에는 expo start 하나면 충분하다

네이티브 앱이 이미 설치되어 있고 화면 코드만 수정했다면 다시 컴파일할 필요가 없습니다.

npx expo start

자주 쓰는 옵션은 이 정도입니다.

옵션 | 설명
--android, -a | 연결된 Android 기기나 Emulator에서 실행
--ios, -i | iOS Simulator에서 실행
--web, -w | 웹 브라우저에서 실행
--dev-client, -d | Expo Go 대신 설치된 개발 빌드로 실행
--go, -g | Expo Go를 실행 대상으로 사용
--clear, -c | Metro 캐시를 지우고 시작
--lan | 같은 네트워크에서 연결. 기본값
--localhost | 개발 중인 Mac에서만 접속
--tunnel | 서로 다른 네트워크에서 터널로 연결
--port 8082 | Metro가 사용할 포트 변경
--offline | 외부 네트워크 요청을 건너뛰고 시작

같은 Wi-Fi인데 휴대폰이 Metro에 붙지 않을 때는 터널이 편합니다.

npx expo start --tunnel

터널은 LAN보다 느리고 URL이 외부에서 접근 가능한 형태가 되므로 개발 중 연결 문제를 피하는 용도로만 사용합니다.

터미널에서 자주 누르는 키

npx expo start를 실행한 터미널에서는 명령을 다시 입력하지 않고 키 하나로 기기를 열 수 있습니다.

키 | 기능
A | 연결된 Android 기기에서 실행
Shift + A | Android 기기나 Emulator 선택
I | 기본 iOS Simulator에서 실행
Shift + I | iOS Simulator 선택
R | 앱 새로고침
M | 개발자 메뉴 열기
S | Expo Go와 개발 빌드 전환
J | React Native DevTools 열기
? | 전체 단축키 표시

Android 실기기에서 실행하기

휴대폰에서 개발자 옵션과 USB 디버깅을 켜고 Mac에 연결합니다. 연결 상태는 adb로 확인합니다.

adb devices -l

상태가 device면 준비가 끝난 것입니다. unauthorized가 나오면 휴대폰 화면에 뜬 USB 디버깅 허용 창을 승인합니다.

개발 빌드는 다음처럼 설치합니다.

npx expo run:android --device

스플래시나 Release 동작을 확인할 때는 빌드 변형을 바꿉니다.

npx expo run:android --device --variant release

Android Emulator에서 실행하기

Android Studio의 Device Manager에서 가상 기기를 먼저 실행한 뒤 다음 명령을 사용합니다.

npx expo run:android

여러 기기가 실행 중이면 --device를 붙여 선택합니다. SDK 56 환경에서는 Android SDK Platform 36과 JDK 17 구성이 기준입니다.

앱이 이미 설치된 다음부터는 npx expo start를 실행하고 A 또는 Shift + A만 눌러도 됩니다.

Android 빌드 옵션

옵션 | 설명
--device | 실기기나 Emulator 선택
--variant debug | 기본 개발 빌드
--variant debugOptimized | SDK 54 이상에서 사용할 수 있는 빠른 개발용 빌드
--variant release | Android Release 빌드
--no-build-cache | 네이티브 빌드 캐시를 지우고 다시 빌드
--no-bundler | Metro를 시작하지 않고 네이티브 앱만 빌드
--no-install | 의존성 설치 생략
--app-id <id> | 실행할 Android Application ID 지정
--binary <path> | 기존 APK 또는 AAB 설치
--port <number> | Metro 포트 변경

iPhone 실기기에서 실행하기

iPhone은 Xcode와 코드 서명 설정이 필요합니다. iOS 16 이상에서는 설정 → 개인정보 보호 및 보안 → 개발자 모드도 켜야 합니다.

기기를 Mac에 연결하고 신뢰 설정을 승인한 뒤 실행합니다.

npx expo run:ios --device

프로젝트에는 고유한 ios.bundleIdentifier가 있어야 하며 Xcode에 Signing 설정이 준비되어 있어야 합니다.

Release 구성은 다음과 같습니다.

npx expo run:ios --device --configuration Release

이 명령으로 만든 로컬 Release 빌드는 App Store 제출용 서명 빌드와는 다릅니다. 스토어 배포 파일은 EAS Build나 Xcode Archive 절차로 따로 만듭니다.

iOS Simulator에서 실행하기

Xcode에 Simulator 런타임이 설치되어 있다면 다음 명령으로 실행할 수 있습니다.

npx expo run:ios

특정 Simulator를 고르려면 --device를 붙입니다.

npx expo run:ios --device

Simulator가 열리지 않을 때는 직접 실행해도 됩니다.

open -a Simulator

Simulator에는 카메라와 일부 센서 같은 실제 하드웨어가 없으므로 마지막 확인은 iPhone에서도 해보는 편이 안전합니다.

iOS 빌드 옵션

옵션 | 설명
--device | iPhone 또는 Simulator 선택
--configuration Debug | 기본 개발 빌드
--configuration Release | iOS Release 빌드
--scheme <scheme> | 빌드할 Xcode Scheme 지정
--no-build-cache | Derived Data를 지우고 다시 빌드
--no-bundler | Metro를 실행하지 않음
--no-install | 패키지와 CocoaPods 설치 생략
--binary <path> | 기존 .app 또는 .ipa 설치
--output <path> | 빌드 결과를 지정한 폴더에 복사
--port <number> | Metro 포트 변경

Simulator용 앱만 만들고 설치하지 않을 수도 있습니다.

npx expo run:ios --configuration Release --device generic --output ./build

prebuild를 다시 해야 하는 순간

아래 항목은 Metro 재시작만으로 반영되지 않습니다.

app.json 또는 app.config.js의 config plugin

앱 아이콘과 스플래시 이미지

Android·iOS 권한

네이티브 모듈 추가

Application ID나 Bundle Identifier

네이티브 폴더가 없다면 expo run이 자동으로 생성합니다. 이미 android/나 ios/가 있다면 기존 폴더를 그대로 사용하므로 직접 동기화해야 합니다.

npx expo prebuild --platform android --clean
npx expo prebuild --platform ios --clean

두 플랫폼을 모두 다시 만들려면 다음처럼 실행합니다.

npx expo prebuild --clean

--clean은 기존 네이티브 폴더를 삭제하고 재생성합니다. android/나 ios/를 직접 수정해서 관리하는 프로젝트라면 변경 내용을 먼저 백업하거나 config plugin으로 옮겨야 합니다.

INSTALL_FAILED_VERSION_DOWNGRADE가 나왔을 때

Android 실기기에 Release APK를 설치하다가 다음 오류를 만날 수 있습니다.

INSTALL_FAILED_VERSION_DOWNGRADE: Downgrade detected

기기에 설치된 앱의 versionCode가 로컬 APK보다 높을 때 Android가 이전 버전 설치를 막는 오류입니다. Play Store에서 받은 앱 위에 로컬 APK를 설치할 때 자주 만납니다.

빠르게 테스트하려면 기존 앱을 삭제하고 다시 설치할 수 있습니다.

adb uninstall <application-id>
npx expo run:android --device --variant release

다만 adb uninstall은 해당 앱의 로그인 정보와 로컬 데이터를 함께 삭제합니다.

versionCode만 높이는 방법은 기존 앱과 로컬 APK의 서명 키가 같을 때만 업데이트로 동작합니다. Play Store 앱과 로컬 디버그 서명이 다르면 다음에는 서명 불일치 오류가 발생합니다. 운영 앱을 기기에 남겨야 한다면 개발 빌드의 Application ID를 별도로 두는 방법이 가장 덜 번거롭습니다.

문제가 생겼을 때 반복해서 쓰는 명령

Metro 캐시가 의심될 때:

npx expo start --clear

Expo SDK와 패키지 버전이 맞는지 확인할 때:

npx expo install --check
npx expo install --fix

프로젝트 전체 설정을 점검할 때:

npx expo-doctor

Expo가 실제로 해석한 네이티브 설정을 볼 때:

npx expo config --type prebuild
npx expo config --type prebuild --json

네이티브 빌드 캐시까지 지워야 할 때:

npx expo run:android --no-build-cache
npx expo run:ios --no-build-cache

저는 이렇게 구분해서 외운다

화면 코드만 바꿨으면 npx expo start를 실행합니다. 아이콘, 스플래시, 권한, config plugin, 네이티브 라이브러리를 바꿨으면 prebuild 후 run으로 다시 빌드합니다.

기기를 골라야 하면 --device, Android Release는 --variant release, iOS Release는 --configuration Release입니다. 이 네 가지만 구분해도 개발 중 불필요한 재빌드가 많이 줄어듭니다.

참고한 공식 문서

Expo CLI

로컬 앱 개발

Android Studio Emulator

iOS Simulator

iOS Developer Mode

Expo SDK 56 SplashScreen