· Workflow · 9분 읽기

React Native 앱의 App Store 스크린샷 만들기 (2026)

React Native 앱의 App Store 스크린샷 만들기 (2026)
TL;DR. React Native에는 공식 스크린샷 파이프라인이 없어요. 원본 프레임을 캡처하는 현실적인 선택지는 Fastlane(iOS의 XCUITest, Android의 screengrab/Espresso), Detox(RN 전용으로 셋 중 가장 쉬움), 또는 시뮬레이터에서 수동 캡처예요. 어떤 방법을 선택하든 날것의 앱 스크린샷만 만들어져요 — 캡션, 기기 프레임, 현지화 버전이 있는 스토어용 캐러셀로 만드는 것은 별도의 마케팅 단계예요. 연간 몇 차례 출시하는 팀 대부분에게는 수동 캡처 + 브라우저 합성이 하루 종일 Fastlane 설정하는 것보다 낫습니다.

첫 React Native 앱을 App Store에 출시할 때 아무도 알려주지 않는 사실이 있어요. 스토어가 요구하는 스크린샷을 생성하는 내장 방법이 없다는 거예요. 네이티브 iOS 개발자는 Xcode의 UI 테스트 레코더를 사용하고, 네이티브 Android 개발자는 빌드에 Espresso가 내장돼 있어요. React Native는 양쪽 위에 얹혀 있고, 실제 앱 로직은 JavaScript로 실행돼요 — 그 어떤 도구도 JS가 존재한다는 사실을 몰라요. 그 간극을 직접 메워야 해요.

이 글은 뉴 아키텍처 시대(RN 0.7x 이상, 2026)에서 실제로 작동하는 방법들을 구체적인 명령어와 함께 설명해요. 각 선택지에는 실제 비용이 있기 때문에 솔직하게 이야기해요. 그런 다음 캡처 이후 단계인 마케팅 합성과 현지화를 다루는데, 이는 소스 프레임을 어떻게 캡처하든 상관없이 별개의 문제예요.

진짜 문제: 공식 파이프라인 없음

App Store Connect는 정확한 픽셀 크기의 스크린샷을 요구하며, 지원하는 기기 클래스와 로케일마다 각각 하나씩 있는 게 이상적이에요. Google Play는 별도의 크기를 요구해요. 네이티브 iOS 프로젝트는 XCUITest로 시뮬레이터를 조작해 프레임을 추출할 수 있어요. React Native도 기술적으로는 가능하지만, 작성한 테스트는 JavaScript 컴포넌트가 아닌 네이티브 셸 — 번들된 바이너리 — 을 대상으로 실행돼요. JS를 렌더링하는 블랙박스를 자동화하는 거예요.

이 차이는 생각보다 중요해요. 스크린샷 자동화가 React 코드와 무관한 이유로 깨진다는 뜻이에요 (Metro 번들러가 실행 중이 아니거나, 시뮬레이터가 권한 다이얼로그에서 멈추거나, 네이티브 빌드가 JS와 어긋났거나). 또한 익숙한 RN 스택이 아닌 두 가지 네이티브 테스트 프레임워크를 배워야 한다는 뜻이기도 해요. 이를 해결하는 세 가지 진지한 방법이 있어요. 출시 빈도에 맞게 선택하세요.

옵션 1 — Fastlane snapshot (iOS)과 screengrab (Android)

Fastlane은 대표적인 오픈소스 모바일 자동화 프레임워크이고, 스크린샷 모듈은 가장 검증된 선택지예요. 하지만 네이티브 프로젝트용으로 만들어졌고 RN을 겨우 허용하는 수준이라 React Native에서 설정하기 가장 번거롭기도 해요.

iOS, snapshot 사용. Xcode에 UI 테스팅 타겟을 추가하고 Swift로 XCUITest 케이스를 작성해 캡처하고 싶은 각 화면으로 앱을 조작해요. fastlane snapshot init을 실행하면 SnapfileSnapshotHelper.swiftfastlane/ 폴더에 생성돼요. 테스트에서 setupSnapshot(app)을 호출하고 앱을 실행한 뒤 각 상태에서 snapshot("01_home")을 호출해요. 올바른 결과를 얻으려면 Xcode 내부가 아닌 터미널에서 fastlane snapshot으로 실행해야 해요. Snapfile에 설정된 모든 시뮬레이터와 로케일을 순회하며 PNG를 fastlane/screenshots/에 저장해요.

React Native 특이사항: snapshot은 컴파일된 앱을 실행하는데, 디버그 빌드에서는 Metro 번들러가 이미 실행 중이어야 해요. 따라서 Fastfile(또는 래퍼 스크립트)에서 먼저 Metro를 시작해야 해요 — 흔히 쓰는 방법은 snapshot을 호출하기 전에 백그라운드 tmux 세션에서 npx react-native start를 실행했다가, 완료 후 종료하는 거예요. JS 번들이 포함된 릴리즈 빌드는 이를 피할 수 있지만 실행마다 전체 릴리즈 빌드 비용이 들어요.

Android, screengrab 사용. 완전히 다른 프레임워크예요. screengrab은 Espresso를 사용해요. JUnit 계측 테스트 안에 Screengrab.screenshot("name")을 추가하고, 권한(DISABLE_KEYGUARD, WAKE_LOCK, CHANGE_CONFIGURATION, 저장소 권한)을 선언하고, ./gradlew assembleDebug assembleAndroidTest로 디버그 APK와 테스트 APK를 빌드한 뒤 fastlane screengrab을 실행해요. 결과물은 fastlane/metadata/android/에 저장돼요. iOS와 마찬가지로 Metro와 에뮬레이터가 이미 실행 중이어야 해요 — screengrab이 대신 시작해주지 않아요.

장점:

  • CI 통합, 차이 없음. 파이프라인에 연결하면 매 릴리즈 빌드마다 스크린샷이 재생성돼 항상 출시된 앱과 일치해요.
  • 실제 로케일별 렌더링. 각 로케일이 실제 로케일 설정으로 시뮬레이터/에뮬레이터에서 실행되므로 날짜, 숫자, 통화가 모두 네이티브로 렌더링돼요 — 디자인 도구에서 흉내낸 게 아니에요.
  • 무료, 오픈소스, 성숙. 구독 없음, 방대한 커뮤니티, 알려진 실패 패턴이 잘 정리돼 있어요.

단점 (솔직하게 따져보세요):

  • 두 개의 네이티브 테스트 스위트를 유지해야 해요. iOS용 XCUITest(Swift), Android용 Espresso/JUnit(Kotlin/Java) — RN 개발자에게는 익숙하지 않은 스택이 두 개예요.
  • JS 로직이 아닌 네이티브 셸을 테스트해요. 테스트가 렌더링된 네이티브 뷰를 검증하며 컴포넌트 트리를 인식하지 못해요.
  • 처음 설정에 하루 이틀이 걸려요. Metro 번들러 연동은 CI에서 불안정한 실행의 반복적인 원인이에요.
  • 출력은 날것의 프레임이에요. 캡션, 기기 프레임, 그라디언트, 캐러셀 없음 — 시뮬레이터 해상도의 앱 UI 그 자체만 있어요.
  • iOS는 Mac 필요. 시뮬레이터는 Xcode가 필요해요.

합성 문제에 대한 더 자세한 비교는 Fastlane snapshot vs 노코드 App Store 스크린샷Mokbi vs Fastlane 비교를 참고하세요.

옵션 2 — Detox 스크린샷 (React Native 전용)

Detox는 Wix 팀이 React Native를 위해 만든 그레이박스 엔드투엔드 테스트 프레임워크예요. 이미 e2e 테스트에 Detox를 쓰고 있다면 스크린샷은 거의 공짜나 다름없고, 러닝커브도 어차피 올라야 할 것이에요 — Swift나 Kotlin이 아닌 JavaScript API니까요.

캡처 호출은 어떤 테스트에서도 한 줄이에요:

// full screen
const path = await device.takeScreenshot('01_home');

// a single element
await element(by.id('paywallRoot')).takeScreenshot('paywall');

이미지가 아티팩트로 저장되는지 여부는 --take-screenshots 플래그(none, failing, manual, all)로 제어하며 .detoxrc.js에서 설정해요. manual 또는 all 모드에서 통과한 테스트는 <artifacts-location>/✓ [test name]/[name].png에 저장돼요. 동일한 Detox 매처로 앱을 각 상태로 조작한 뒤 스냅샷을 찍어요.

장점:

  • JavaScript API예요. 앱과 같은 언어로 테스트를 작성해요 — 별도의 네이티브 테스트 스위트를 소유할 필요가 없어요.
  • 그레이박스라 RN을 이해해요. Detox는 앱의 브릿지/JSI와 동기화해 유휴 상태를 기다리므로 XCUITest의 맹목적 타이머 대기보다 훨씬 안정적인 스크린샷을 만들어요.
  • 하나의 프레임워크, 두 플랫폼. 동일한 테스트 파일로 iOS와 Android를 캡처해요.
  • 이미 있을 가능성이 높아요. e2e 테스트를 한다면 이미 Detox가 있을 테고, 스크린샷 추가 비용은 미미해요.

단점:

  • 처음부터 Detox를 구축하는 건 만만치 않아요. 네이티브 빌드 설정, 전용 테스트 빌드, 에뮬레이터/시뮬레이터 설정이 필요해요. 아직 쓰지 않고 있다면 상당한 투자예요.
  • 로케일 처리는 직접 해야 해요. snapshot의 Snapfile처럼 모든 App Store 로케일을 자동으로 순회하지 않아요. 로케일 변경을 스크립팅하거나 다른 설정으로 재실행해야 해요.
  • 출력은 여전히 날것의 프레임이에요. Fastlane과 동일 — 마케팅 레이어 없이 날 앱 UI예요.
  • 스크린샷이 호스트 머신마다 다를 수 있어요. Detox의 알려진 이슈로, CI에서 비교하면 문제가 되지만 스토어 에셋으로는 무해해요.

옵션 3 — 수동 캡처 (가장 단순하고, 과소평가됨)

iOS 시뮬레이터나 Android 에뮬레이터를 열고, 직접 앱의 각 화면으로 이동해 프레임을 캡처해요. iOS에서는 시뮬레이터의 Cmd-S로 올바른 크기의 PNG를 바탕화면에 저장할 수 있고, xcrun simctl io booted screenshot home.png를 터미널에서 실행하면 같은 결과를 얻으며 간단히 스크립팅할 수 있어요. Android에서는 에뮬레이터의 카메라 버튼이나 adb exec-out screencap -p > home.png로 화면을 캡처해요. 실제 기기도 사용 가능해요 — 캡처 후 AirDrop이나 파일 전송으로 옮기면 돼요.

이 방법은 너무 쉽게 무시돼요. 설정이 전혀 없고, CI가 없으니 CI에서 깨지지도 않아요. 연간 몇 번 출시하는 앱에는 소스 프레임을 확보하는 가장 빠른 방법이에요. 단점은 명확하고 실제예요. 수동이기 때문에 자동으로 재생성되지 않고, 화면을 변경하면 다시 캡처하기 전까지 이전 버전을 쓰게 돼요. 5개 화면 캐러셀이라면 릴리즈당 10분 — 1년에 두 번 실행할 테스트 자동화를 유지하는 것보다 저렴해요.

모두가 잊어버리는 부분: 합성과 현지화

세 가지 옵션이 공통적으로 가진 것이 있어요. 모두 날것의 앱 스크린샷을 만들어요. 그런데 날것의 스크린샷은 스토어에서 전환을 일으키지 않아요. 실제로 다운로드를 유도하는 App Store 캐러셀에는 화면 주변의 기기 프레임, 혜택을 설명하는 한 줄 캡션, 흰 앱 배경이 아닌 다른 배경, 다섯 패널 전체의 일관성이 있어요. 위의 캡처 도구들은 그 어느 것도 만들어주지 않아요 — 날것의 프레임에서 멈춰요. 이건 도구의 결함이 아니에요. 다른 일이에요.

이 단계에서 Mokbi가 자리를 잡아요. 경계를 명확히 하자면: Mokbi는 소스 스크린샷을 캡처하지 않아요 — 그건 위의 시뮬레이터, 기기, Fastlane/Detox가 할 일이에요. Mokbi가 하는 건 그 다음의 마케팅 합성과 현지화예요. 날것의 프레임을 브라우저 에디터에 드롭하고, 실제 기기 프레임으로 감싸고, 캡션을 추가하고, 멀티 패널 캐러셀을 구성한 뒤 원클릭으로 50개 언어로 캡션을 번역하고 모든 스토어 크기로 일괄 내보내기해요. 워터마크 미리보기로 무료 디자인이 가능하고, 무제한 내보내기와 게시는 구독으로 제공돼요 — Solo €29.99/mo(앱 1개) 또는 Studio €49.99/mo(최대 5개 앱), 일회성 구매는 없어요. 깔끔하게 연결되는 이유는 캡처 파이프라인이 시도조차 하지 않는 문제를 해결하기 때문이에요. PNG 폴더를 Photoshop 없이, 50개 언어를 일일이 크기 조정 없이 현지화된 스토어용 캐러셀로 바꾸는 거예요.

현실적인 통합 워크플로

  1. 소스 프레임 캡처. 하나를 선택하세요. 잦은 릴리즈라면 CI의 Fastlane(snapshot + screengrab), 이미 e2e 테스트를 실행한다면 Detox, 드문 릴리즈라면 수동 시뮬레이터 캡처. 결과물: 화면별, 기기별 날 PNG 폴더.
  2. 합성, 캡션, 프레임 적용. 날 프레임을 브라우저 에디터에 드롭하세요. 기기 프레임을 추가하고, 혜택 캡션을 작성하고, 다섯 패널 캐러셀을 만들고, 배경을 선택하세요.
  3. 번역. 원클릭으로 50개 언어의 캡션을 일괄 번역하고, 가장 중요한 언어는 직접 검토하세요.
  4. 일괄 내보내기. App Store Connect와 Google Play에 필요한 모든 로케일과 크기를 한 번에 내보내기해요.
  5. 다음 릴리즈에서 교체. 변경된 프레임을 다시 캡처하고(Fastlane/Detox 재실행 또는 수동 캡처), 저장된 프로젝트를 열어 스크린샷을 교체한 뒤 다시 내보내기해요. 캡션과 번역 작업은 이미 완료된 상태예요.

자동화를 건너뛸 수 있는 경우

연 1~3회 출시하는 경우 — 대부분의 인디 React Native 앱이 그렇죠 — Fastlane이나 Detox 설정 비용은 거의 회수되지 않아요. XCUITest와 Metro 번들러 연동을 하루 동안 설정해도 연간 두 번 10분의 수동 캡처를 절약하는 셈이에요. 그 수지는 맞지 않아요. 시뮬레이터에서 직접 캡처하고, 브라우저에서 합성과 현지화를 하면 자동화를 한 번 구성하는 것보다 총 시간이 더 적게 들어요.

자동화가 가치를 발휘하는 건 주 단위 또는 일 단위로 출시할 때, 스크린샷 차이가 반복적인 버그가 될 때, 또는 여러 앱 포트폴리오를 운영해 앱당 캡처 비용이 곱해질 때예요. 그 규모에서는 CI의 Fastlane(또는 스택에 이미 있다면 Detox)이 캡처 단계에서 올바른 선택이에요 — 그래도 마케팅 레이어를 위해 브라우저 합성 도구를 함께 써야 해요. 어떤 캡처 파이프라인도 완성된 캐러셀을 만들어주지 않으니까요.

내보내기 전에 대상을 확인해두는 게 좋아요. 실제로 업로드해야 하는 App Store 스크린샷 크기와 심사가 거절되는 App Store 스크린샷 요구사항을 한 번 제대로 확인해두면 App 심사와의 왕복 한 번을 아낄 수 있어요.

다음으로 읽을 내용

에디터 열기 →