학습 목표·선수 지식: preview APK와 개발 빌드를 구분하고 빌드 ID에 맞는 Android 설치 결과를 확인합니다. 첫 화면 프로젝트와 Expo 계정, Android 기기 또는 에뮬레이터가 필요합니다.
이 글에서 배우는 내용
화면 실행 다음 단계는 Android에 설치할 APK를 만드는 것입니다. 앱 식별자와 preview 프로필을 정하고 EAS 프로젝트를 연결한 뒤, 완료된 빌드를 기기에 설치하는 절차를 따라갑니다. 작성 환경에서는 로컬 타입·설정·JavaScript 번들만 검증했으며 실제 EAS 클라우드 빌드와 설치는 실행하지 않았습니다.
목차
- 첫 결과물은 Android preview APK로 정하기
- 앱 식별자와 로컬 상태 확인하기
- Expo 계정과 EAS 프로젝트 연결하기
- eas.json에서 preview 프로필 정하기
- 빌드 요청과 설치 확인 순서
- 성공 기준과 실패 시 다음 단계
첫 결과물은 Android preview APK로 정하기
먼저 Expo 첫 화면 실습 프로젝트를 준비하고 기본 UI와 Router 학습을 마친 상태에서 진행하세요. 이 글은 first-screen처럼 아직 스토어에 배포하지 않은 연습 앱을 기준으로 합니다. 기존 출시 앱은 식별자나 서명 키를 새로 만들지 말고 기존 프로젝트 정보를 유지해야 합니다.
| 실행/산출물 | 확인하는 범위 | 이번 목표와의 관계 |
|---|---|---|
| Expo Go에서 화면 보기 | 이미 만들어진 Expo Go 내부에서 앱 코드 실행 | 우리 앱의 설치 파일 생성과 다름 |
| Android preview APK | 서명된 설치 파일을 Android에 직접 설치 | 이번 글에서 독자가 완성할 결과 |
| Android production AAB | Google Play 배포에 적합한 번들 | 직접 설치용 APK가 필요한 첫 실습 이후 |
| iOS 시뮬레이터/기기 빌드 | 별도의 플랫폼·서명·실행 환경 | Android APK 실습과 분리해 진행 |
Expo APK 안내는 직접 설치하려면 APK가 필요하다고 설명합니다. 처음부터 두 플랫폼과 스토어 제출을 한꺼번에 진행하지 않고 Android 한 플랫폼으로 빌드부터 설치까지의 경로를 확인합니다. Android APK를 만들 때 Google Play 제출 계정은 필요하지 않지만 Expo 계정과 빌드 서비스 이용 가능 상태는 필요합니다.

앱 식별자와 로컬 상태 확인하기
앞 실습에서 생성한 App.tsx와 app.json, package-lock.json을 유지합니다. package.json 옆에 다음 app.config.ts를 추가하세요. 이미 app.config.ts가 있다면 새로 덮어쓰지 말고 android.package 설정을 현재 반환 객체에 합칩니다.
app.config.ts
import type { ConfigContext, ExpoConfig } from 'expo/config';
export default ({ config }: ConfigContext): ExpoConfig => ({
...config,
name: config.name ?? 'first-screen',
slug: config.slug ?? 'first-screen',
android: {
...config.android,
package: 'com.example.firstscreen',
},
});
com.example.firstscreen은 로컬 검증용 예시 식별자입니다. 첫 원격 빌드 전에는 본인이 관리하는 고유한 역도메인 형식으로 바꾸세요. name은 사용자에게 표시되는 이름이고 package는 Android 앱을 구분하는 식별자입니다. …config와 …config.android는 기존 설정을 유지하므로 생성된 아이콘 설정이나 나중에 연결할 EAS 정보를 잃지 않습니다.
터미널
npx tsc --noEmit
npx expo config --type public
npx expo export --platform android --output-dir dist-android
app config 공식 문서는 정적 app.json을 동적 설정 함수가 받아 확장하는 방식을 설명합니다. 출력에서 name, slug, android.package가 의도와 맞는지 확인합니다. app config에는 공개 앱에 포함되면 안 되는 비밀번호나 비밀 토큰을 넣지 않습니다. 타입 오류와 번들 오류가 있다면 원격 빌드를 요청하기 전에 수정합니다.
Expo 계정과 EAS 프로젝트 연결하기
여기부터는 독자가 자신의 Expo 계정에서 실행하는 절차입니다. 이 글을 작성하면서 로그인하거나 원격 프로젝트를 생성하지 않았습니다. EAS 첫 빌드 문서는 EAS CLI 설치 대신 npx eas-cli@latest 사용도 안내합니다. 아래처럼 한 방식으로 통일하세요.
터미널
npx eas-cli@latest login
npx eas-cli@latest whoami
npx eas-cli@latest build:configure --platform android
whoami 결과가 본인의 계정인지 확인한 뒤 프로젝트 연결 질문에서 개인 계정 또는 올바른 조직을 선택합니다. 새 연습 앱이면 새 프로젝트를 연결하고, 이미 연결된 앱이면 그 프로젝트를 유지합니다. CLI가 출력하는 프로젝트 URL을 열어 앱 이름과 소유자가 맞는지 확인하세요. 이 명령은 로컬 코드만 검사하는 작업과 달리 EAS 프로젝트 연결을 수행합니다.
동적 app.config.ts를 쓰면 CLI가 설정을 자동 수정하지 못하고 extra.eas.projectId를 직접 추가하라고 안내할 수 있습니다. CLI가 발급한 실제 projectId를 app.json의 expo.extra.eas.projectId에 합쳐 넣으세요. 이 예제의 설정 함수가 기존 config를 펼치므로 그 값이 최종 설정에 남습니다. 임의의 UUID나 다른 앱의 ID를 복사하지 마세요. 연결 후 expo config 출력에서 해당 ID가 유지되는지 다시 확인합니다.
eas.json에서 preview 프로필 정하기
프로필은 빌드 목적별 설정 묶음입니다. 신규 연습 프로젝트라면 생성된 eas.json을 아래 최소 구성으로 바꿀 수 있습니다. 기존 프로젝트라면 다른 프로필을 보존하면서 build.preview만 추가하거나 조정하세요.
eas.json
설정 예시: eas.json의 해당 객체에 병합합니다. 기존 설정은 보존합니다.
{
"build": {
"preview": {
"distribution": "internal",
"android": { "buildType": "apk" }
}
}
}
distribution: internal은 내부 설치 목적, android.buildType: apk는 Android 산출물 형식입니다. preview는 사람이 선택한 프로필 이름이며 --profile preview로 선택해야 합니다. 이 구성은 developmentClient를 켜지 않았으므로 개발 도구 없이 앱을 확인하는 preview 흐름입니다.
EAS 프로필 문서에서 development 빌드는 expo-dev-client를 사용한 개발 환경이고 preview는 실제 배포에 가까운 조건으로 확인하는 용도입니다. development 프로필을 나중에 쓰려면 먼저 npx expo install expo-dev-client를 수행하고 해당 목적에 맞는 별도 프로필을 구성합니다. 지금은 preview APK 설치를 먼저 끝내세요.

빌드 요청과 설치 확인 순서
계정·프로젝트·프로필을 확인했다면 아래 빌드를 요청합니다. 서비스의 현재 사용 한도와 대기 상태는 본인 계정에서 확인하세요. 여기서는 가격이나 무료 빌드 횟수를 고정해 안내하지 않습니다.
터미널
npx eas-cli@latest build --platform android --profile preview
npx eas-cli@latest build:list --platform android
처음 만드는 연습 앱에서 Android 서명 키 생성 여부를 묻는다면 EAS가 새 keystore를 관리하도록 선택할 수 있습니다. 이미 배포한 앱이라면 기존 서명을 사용해야 합니다. 터미널에 표시되는 빌드 상세 URL에서 대상 플랫폼과 preview 프로필, 업로드한 코드, 로그를 확인하고 완료 상태를 기다립니다. 요청 접수나 대기열 진입은 빌드 성공이 아닙니다.
완료된 빌드 상세 화면에서 APK 링크를 Android 기기로 열어 설치하고 앱 아이콘을 눌러 실행합니다. Android가 해당 출처의 앱 설치 허용을 요청하면 본인이 생성한 빌드인지 확인한 뒤 진행하세요. Android 에뮬레이터가 준비되어 있다면 다음 명령으로 해당 빌드를 선택해 설치할 수도 있습니다.
터미널
npx eas-cli@latest build:run --platform android
최근 빌드가 여러 개라면 목록에서 방금 확인한 빌드 ID를 선택합니다. 설치 후 개발 서버를 종료한 상태에서도 기본 첫 화면이 열리는지 확인하세요. 이 실습의 화면은 외부 API를 사용하지 않는 정적 카드이므로 preview APK에 포함된 번들만으로 보이는 것이 기대 결과입니다. 실제 서비스 화면은 서버 연결이 별도로 필요할 수 있습니다.
설치 오류를 빌드 실패와 구분하기
Android SDK Platform-Tools가 설치된 컴퓨터에서는 아래 명령을 차례로 실행할 수 있습니다. downloads/preview.apk에는 방금 완료된 빌드 상세 화면에서 받은 APK를 둡니다. USB 디버깅 승인 뒤 adb devices에서 상태가 device인 대상을 확인하세요. 여러 기기가 있으면 adb -s 기기식별자 install -r downloads/preview.apk처럼 대상을 명시합니다.
adb devices
adb install -r downloads/preview.apk
INSTALL_FAILED_UPDATE_INCOMPATIBLE은 같은 package에 다른 서명의 앱이 설치된 경우를 먼저 확인합니다. 출시 앱의 키를 새로 만들지 마세요. 연습 앱을 제거하면 로컬 데이터가 지워지므로 필요 데이터를 먼저 보존합니다. INSTALL_FAILED_VERSION_DOWNGRADE는 기존 앱보다 versionCode가 낮은 경우를 확인합니다. 파일이 AAB라면 이 설치 명령의 대상이 아니므로 preview APK 산출물로 돌아갑니다. 설치 후 개발 서버를 끄고 앱을 완전히 종료·재실행해 카드가 보이는지 확인하세요.
성공 기준과 실패 시 다음 단계
| 단계 | 통과 증거 | 부족한 증거 |
|---|---|---|
| 로컬 준비 | 타입 검사·최종 설정·Android JS 번들 성공 | Expo Go 화면만 열림 |
| EAS 빌드 | 해당 빌드 ID가 완료되고 APK 산출물이 존재 | 업로드 또는 큐 진입 |
| 설치 | 기기에서 APK 설치 및 앱 실행 | 파일 다운로드만 완료 |
| 화면 확인 | 개발 서버 없이 기대한 첫 화면 표시 | 앱 아이콘만 생김 |
작성 환경에서는 App.tsx와 위 app.config.ts의 타입 검사, 최종 android.package 해석, eas.json JSON 문법 및 preview 값 확인, Android JavaScript 번들 생성을 수행했습니다. 서명·원격 네이티브 컴파일·APK 다운로드·기기 설치는 수행하지 않았으므로 실제 첫 빌드 성공 사례로 주장하지 않습니다. 독자는 마지막 두 단계까지 직접 확인하고 빌드 ID·프로필·앱 버전을 기록해야 합니다.
실패했다면 실패한 단계의 첫 구체적인 오류부터 읽습니다. 번들 생성 실패와 네이티브 컴파일 실패, 서명 오류는 원인이 다릅니다. 이후 Expo EAS Build 원격 빌드 오류 해결로 이동하면 성공 조건을 아는 상태에서 실패 범위를 좁힐 수 있습니다. 캐시 삭제나 키 재생성부터 시작하지 마세요.
시작·완성 예제 파일
ZIP에는 시작본(starter), 완성본(complete), 실행 안내가 들어 있습니다. 압축을 푼 뒤 README의 준비 사항과 실행 순서를 확인하세요.
EAS 빌드는 본인 Expo 계정과 프로젝트 설정이 필요합니다. APK 설치와 네이티브 기기 동작은 직접 확인하세요.
문서·검증 기준 (2026-09-13): 해당 기능의 Expo 공식 문서와 코드 구조를 대조했습니다. 설치 버전은 프로젝트 Expo SDK에 맞는 npx expo install 결과와 lockfile을 기준으로 합니다. 이번 개정에서는 실제 Android·iOS 기기 실행, 원격 EAS 빌드, 외부 인증 서버 연동을 수행하지 않았습니다. 본문의 기기 동작은 독자가 확인할 기대 결과입니다.
이 글이 도움이 되었나요?
Expo 학습 순서
필수 9개 · 전체 13개
읽음 기록 관리
전체 과정 목차 (13개)
- 필수 학습 · Expo 첫 앱 만들기: 설치·프로젝트 생성부터 첫 화면 실행까지
- 필수 학습 · Expo Safe Area 사용법: 화면 여백을 안전하게 잡는 방법
- 필수 학습 · Expo Status Bar 사용법: Safe Area와 화면별 설정
- 필수 학습 · Expo vector icons 사용법: 탭바와 커스텀 아이콘 적용하기
- 필수 학습 · Expo KeyboardAvoidingView 사용법: 키보드가 화면을 가릴 때 해결하기
- 필수 학습 · Expo Router 사용법: app 폴더와 Stack Tabs 구조 잡기
- 필수 학습 · Expo WebBrowser 사용법: 외부 링크와 로그인 복귀 처리
- 필수 학습 · Expo SecureStore 사용법: 토큰 저장과 생체 인증 처리
- 선택 참고 · Expo Location 사용법: 현재 위치와 백그라운드 추적 처리
- 선택 참고 · Expo React Native Web 사용법: 앱을 웹으로 확장하기
- 선택 참고 · Expo Metro unable to resolve module 오류 해결: 경로와 캐시
- 필수 학습 · Expo EAS Build 시작하기: Android APK 빌드부터 설치 확인까지 현재 글
- 선택 참고 · Expo EAS Build 오류 해결: 로컬은 되는데 원격 빌드만 실패할 때
새 글 받아보기
RSS 리더에서 BlogFlow의 새 글을 확인할 수 있습니다.