[RN] Expo. 다시 보니 예쁘다.
어색한 사이였던 Expo. 한 번.. 친해져볼까?
오늘 블로그에 작성할 소재를 좀 찾다가..
Expo를 그동안 너무 편견에 쌓인 시선으로 봤던 거 같아서, 이번 프로젝트에 써보면서 한 번 정리해보려고 한다.
사실 나는 알게 모르게 Expo = 코딩 학원용 장난감이라는 공식이 머리에 박혀 있다.
네이티브 코드 한 줄이라도 수정하려면 eject 눌러야 하고, 그 순간 프로젝트 설정 파일이 토사물처럼 쏟아져 나오던 그 시절의 트라우마가 있어서 그냥 쳐다도 안봤다.
근데 기술은 계속 발전하는데 내 머리만 2022년대 초반에 멈춰 있었나 보다.
이번에 각 잡고 공식 문서 파보고, 직접 빌드 돌려보면서 “아, 내가 멍충이였구나” 싶었다.
그래서 요즘은 공홈에서도 많이 권하고 있길래 한 번 다시 어색한 친구에게 말을 걸듯 써보면서 정리해 보려고 한다.
난 왜 Expo와 멀어졌나
내가 RN을 한창 파던 2022년 무렵, Expo는 ‘대혼돈의 시기’였다.
그 땐, 약간… 한 번 써보고 몰려드는 피로감에 나도 모르게 거부감이 생긴 거 같다.
- 공포의 버튼
eject: 당시엔 네이티브 기능 건드리려면 무조건eject를 해야 했다. 이거 누르면 돌아올 수 없는 강을 건너는 거였고, 프로젝트 관리는 지옥이 됐다.
- 문서의 파편화: 당시 EAS(신형)가 막 나오면서 기존 Classic Build(구형)랑 문서가 뒤섞여 있었다. 뉴비가 보기엔 “도대체 뭘 쓰라는 거야?” 싶을 정도로 혼란스러웠다.
- 빈약한 생태계: 지금처럼 Config Plugin이 활성화되지 않아서, 인앱 결제 같은 거 붙이려면 진짜 맨땅에 헤딩해야 했다.
그러니 22년도의 내가 Expo를 거들떠도 안 본 건 합리적인 판단이었다.
패러다임의 변화: Managed에서 CNG로
하지만 2026년인 지금, 상황은 역전됐다.
내가 가장 혐오했던 ‘블랙박스’ 이슈가 해결됐으니까.
요즘 Expo는 CNG (Continuous Native Generation)라는 개념을 민다.
- 과거:
ios,android폴더를 숨기고 못 건드리게 함. (답답함 MAX) - 현재:
app.json설정 파일만 관리하고, 빌드할 때마다ios,android폴더를 ‘새로 생성’해버림.
이게 무슨 소리냐면, 더 이상 eject로 프로젝트를 망칠 필요가 없다는 거다.
Config Plugin이라는 걸 쓰면 네이티브 설정도 JS 코드로 제어가 된다.
즉, “순정 RN의 자유도 + Expo의 편리함”이 섞여있다.
튜토리얼: 일단 빌드부터 돌려보자
그냥 내가 보려고 정리해본다.
Step 1. EAS CLI 설치 & 로그인
npm install -g eas-cli
eas login
Step 2. 프로젝트 설정 (The Recipe)
eas build:configure
이걸 치면 eas.json 파일이 생긴다. Expo의 핵심이다.
{
"cli": {
"version": ">= 7.0.0"
},
"build": {
"development": {
"developmentClient": true,
"distribution": "internal"
},
"preview": {
"distribution": "internal",
"android": {
"buildType": "apk"
}
},
"production": {}
}
}
- development: 나중에 설명할 ‘나만의 개발 앱’ 만들 때 쓴다. (디버깅용)
- preview: 팀원이나 테스터한테 “이거 한번 설치해 봐” 하고 파일(APK) 던져줄 때 쓴다. (스토어 업로드 X)
- production: 진짜 스토어(구글/애플)에 올릴 때 쓴다. (자동으로 AAB 등으로 최적화됨)
Step 3. 빌드 날리기 (Fire!)
이제 클라우드로 코드를 쏘아 올릴 차례다. 테스터용 APK를 뽑고 싶다?
# --profile 뒤에 아까 eas.json에 적은 이름을 넣는 거다.
eas build --platform android --profile preview
명령어 치면 터미널에서 주저리주저리 로그가 올라가고, Expo 대시보드 URL이 나온다.
거기 들어가서 진행 상황 구경하다가, 다 되면 나오는 QR 코드 찍으면 폰에 설치된다.
USB 케이블 찾으러 책상 밑으로 기어 들어갈 필요가 없다.
4. 꿀팁: Development Client (삽질 방지)
Expo를 처음 쓰면 100% 겪는 문제가 있다. 바로 Expo Go 앱의 한계다.
처음엔 스토어에 있는 Expo Go 앱 깔아서 QR 찍고 개발할 거다.
근데 카카오 로그인이나 구글 맵 같은 네이티브 모듈(Native Module)을 추가하는 순간, 앱이 에러를 뿜으며 죽어버린다.
Expo Go에는 그 네이티브 코드가 없으니까.
이때 당황하지 말고 **‘Development Client’**를 만들어야 한다.
쉽게 말해서 “내가 쓴 라이브러리들을 다 포함한 나만의 커스텀 Expo Go”를 만드는 거다.
아까 eas.json에 development 프로필이 이걸 위한거다. 그대로 빌드하면 된다.
# 시뮬레이터용 (iOS) - 맥북 없어도 클라우드가 빌드해서 시뮬레이터 파일 줌
eas build --profile development --platform ios --simulator
# 실제 기기용 (Android)
eas build --profile development --platform android
이거 빌드해서 폰에 깔면, 그게 나만의 런타임이 된다.
거기선 네이티브 라이브러리 다 돌아간다. 이거 모르면 하루 종일 “왜 안 돼?” 한다. 내가 그랬다.
꼭 기억하자.
5. 하지만, 여전히 존재하는 단점 (Critical Review)
찬양만 하면 광고 같으니까, 쓰면서 느낀 ‘현실적인 단점’들도 정리한다.
솔직히 이 부분이 더 중요하다.
Expo는 차갑다.
제일 중요하다.
EAS Build 무료 티어(Free)를 써봤는데, 주말이나 사람 몰리는 시간엔 대기열이 생긴다. “Build queued…” 뜨고 20~30분 멍 때리고 있으면 속 터진다.
돈 내면 우선 처리(Priority) 해주는데, 월 $29다. (아 좀 빡세다…)
돈으로 시간을 살지, 그냥 기다릴지 선택해야 한다.
(2) 앱 용량 증가 (Size Bloat)
Expo SDK가 기본적으로 포함하는 라이브러리들이 있다 보니, 순정 RN(react-native init)으로 만든 것보다 앱 용량이 조금 더 크다.
물론 요즘 폰 용량이 깡패라 큰 문제는 아니지만, 1MB라도 줄이려고 발악하는 최적화 변태들에겐 거슬릴 수 있는 부분이다.
(3) 네이티브 모듈의 호환성
대부분의 유명한 라이브러리(카카오 로그인, 파이어베이스 등)는 Expo용 Config Plugin이 다 있다.
근데 정말 마이너한 네이티브 SDK를 붙여야 한다? 혹은 내가 직접 네이티브 브릿지 코드를 짜야 한다?
할 수는 있을 거 같은데… Config Plugin을 직접 작성해야 해서 러닝 커브가 수직 상승한다.
이때는 “아 그냥 CLI 쓸걸” 하는 생각이 들 수도 있다.
그래서 계속 씀?
정리하자면, **“극단적인 최적화나 특이한 네이티브 기능이 필요한 게 아니라면, 안 쓸 이유가 없다”**는 게 내 결론이다.
단점이 분명히 존재하지만, 그 단점을 덮을 만큼 **‘개발 생산성’**이 너무 좋다.
일단 키스토어 관리 안해도 되는 거 너무 좋고…
혼자 기획하고, 디자인하고, 개발하고, 마케팅까지 해야 하는 1인 개발자(aka 노예) 입장에서, 빌드랑 배포 스트레스를 클라우드에 외주 맡기는 셈 치면 남는 장사다.
유료 결제는 조금 생각해보겠지만… 로컬 빌드로 돌리면 문제 없고(어차피 맥북이야 있으니까) 속도가 좀… 많이 빠르다.
마침.
다른 글 보기
실운영 서버 /home 디렉토리가 통째로 증발했다 (범인은 내부에...)
오픈 일주일 남은 우분투 서버가 먹통이 됨. 해킹인 줄 알고 식은땀 흘렸는데 까보니 시트콤이다.
[RN] Rive로 앱에 생명 불어넣기: 실전 연동 튜토리얼 (feat. 디자인은 돈으로 사자)
Rive를 사용하는 이유와 React Native 연동 핵심 코드 정리. 일주일 삽질 끝에 얻은 '가장 효율적인' 개발 가이드.
출근은 없는데, 퇴근도 없다: 1인 프리랜서로의 일주일을 지내고...
자율근무의 자유를 얻었지만, 시간의 밀도는 더 가혹해졌다. 1인 개발자로 살며 깨달은 시간의 무게와 자율의 공포