Скриншоты App Store для React Native приложений (2026)
Вот что никто не говорит, когда ты публикуешь первое React Native приложение в App Store: встроенного способа сгенерировать нужные магазину скриншоты не существует. Нативные iOS-разработчики тянутся к UI test recorder в Xcode; нативные Android-разработчики имеют Espresso прямо в сборке. React Native работает поверх обеих платформ, а реальная логика приложения выполняется на JavaScript — и ни один из этих инструментов не знает о твоём JS. Мост нужно строить самому.
В этой статье рассмотрены подходы, которые действительно работают в эпоху New Architecture (RN 0.7x и выше, 2026) — с конкретными командами. Честно о затратах, потому что у каждого варианта они есть. Затем — о том, что идёт после захвата: маркетинговая компоновка и локализация — самостоятельная задача, независимо от того, как получены исходные кадры.
Настоящая проблема: нет готового пайплайна
App Store Connect требует скриншоты точных пиксельных размеров — в идеале один набор на класс устройства и один набор на каждую поддерживаемую локаль. Google Play хочет свои размеры. Нативный iOS-проект может управлять симулятором через XCUITest и сохранять кадры; React Native технически тоже может, но тест при этом работает против нативной оболочки — скомпилированного бинарника — а не против JavaScript-компонентов напрямую. Ты автоматизируешь чёрный ящик, который случайно рендерит твой JS.
Это различие важнее, чем кажется. Оно означает, что автоматизация скриншотов ломается по причинам, никак не связанным с React-кодом (Metro bundler не был запущен, симулятор завис на диалоге разрешения, нативная сборка разошлась с JS) — и что кривая обучения — это кривая двух нативных тестовых фреймворков, а не привычного RN-стека. Есть три серьёзных пути. Выбирай по частоте релизов.
Вариант 1 — Fastlane snapshot (iOS) и screengrab (Android)
Fastlane — канонический open-source фреймворк мобильной автоматизации, а его модули для скриншотов — самый проверенный вариант. И вместе с тем самый трудоёмкий в настройке для React Native, потому что они создавались для нативных проектов и лишь терпят RN.
iOS, через snapshot. Добавляешь UI testing target в Xcode и пишешь XCUITest-тесты на Swift, которые доводят приложение до каждого нужного экрана. fastlane snapshot init создаёт Snapfile и SnapshotHelper.swift в папке fastlane/. В тесте вызываешь setupSnapshot(app), запускаешь приложение и вызываешь snapshot("01_home") в каждом нужном состоянии. Запускаешь из терминала командой fastlane snapshot — не из Xcode, иначе корректного вывода не будет. Инструмент перебирает все симуляторы и локали из Snapfile и записывает PNG в fastlane/screenshots/.
Нюанс с React Native: snapshot запускает скомпилированное приложение, которое в debug-режиме требует уже запущенного Metro bundler. Поэтому Fastfile (или скрипт-обёртка) должен сначала стартовать Metro — стандартный приём: запустить npx react-native start в фоновой сессии tmux до вызова snapshot, а после — завершить. Release-сборки со встроенным JS-бандлом избегают этого, но требуют полной release-сборки при каждом прогоне.
Android, через screengrab. Совершенно другой фреймворк: screengrab использует Espresso. Добавляешь вызовы Screengrab.screenshot("name") внутри JUnit instrumented tests, объявляешь разрешения (DISABLE_KEYGUARD, WAKE_LOCK, CHANGE_CONFIGURATION и storage perms), собираешь debug APK и test APK через ./gradlew assembleDebug assembleAndroidTest и запускаешь fastlane screengrab. Вывод попадает в fastlane/metadata/android/. Как и на iOS, Metro и эмулятор должны быть уже запущены — screengrab не стартует их за тебя.
Сильные стороны:
- Интеграция с CI, без расхождений. Подключи к пайплайну — и скриншоты пересоздаются при каждой релизной сборке, всегда соответствуя реальному приложению.
- Настоящий рендеринг на локаль. Каждая локаль запускается в симуляторе/эмуляторе с реальными настройками локали, поэтому даты, числа и валюта отображаются нативно, а не подделываются в дизайн-инструменте.
- Бесплатно, open source, зрелый инструмент. Никаких подписок, огромное сообщество, хорошо известные типы проблем.
Слабые стороны (будь честен с собой):
- Нужно поддерживать два нативных тестовых набора. XCUITest на Swift для iOS, Espresso/JUnit на Kotlin/Java для Android — как RN-разработчик, ты, возможно, столкнёшься с двумя незнакомыми стеками.
- Тестируется нативная оболочка, а не JS-логика. Тесты проверяют нативные вью; они не знают о дереве компонентов.
- Настройка занимает день-два с нуля, а танец с Metro bundler — постоянный источник нестабильных CI-прогонов.
- Результат — сырые кадры. Никаких подписей, рамок устройств, градиентов, карусели — только голый UI приложения в разрешении симулятора.
- Для iOS нужен Mac. Симулятор требует Xcode.
Подробное сравнение конкретно в части компоновки — в статье fastlane snapshot vs no-code скриншоты App Store и сравнении Mokbi vs Fastlane.
Вариант 2 — Detox screenshots (создан для React Native)
Detox — gray-box end-to-end фреймворк для тестирования, созданный специально для React Native командой Wix. Если ты уже используешь Detox для e2e-тестов, скриншоты обходятся почти даром, а кривая обучения та, которую ты в любом случае хотел бы пройти — это JavaScript API, а не Swift или Kotlin.
Вызов захвата — одна строка внутри любого теста:
// 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-матчерами, что используются для assertions, а затем делается снимок.
Сильные стороны:
- JavaScript API. Тесты пишешь на том же языке, что и приложение — никакого второго нативного тестового набора.
- Gray-box, понимает RN. Detox синхронизируется с bridge/JSI приложения и ждёт его idle-состояния — скриншоты значительно стабильнее, чем слепые ожидания по таймауту в XCUITest.
- Один фреймворк для обеих платформ. Один тестовый файл захватывает iOS и Android.
- Скорее всего, он у тебя уже есть, если используешь e2e-тестирование — в таком случае дополнительные затраты на скриншоты минимальны.
Слабые стороны:
- Поднять Detox с нуля непросто — нативная конфигурация сборки, отдельный тестовый билд, настройка эмулятора/симулятора. Если ты его ещё не используешь, это реальные инвестиции.
- Работа с локалями на тебе. Detox не обходит автоматически все локали App Store, как это делает
snapshotчерез Snapfile; смену локали нужно скриптовать или перезапускать с другими настройками. - Результат — по-прежнему сырые кадры. То же, что у Fastlane — голый UI приложения, без маркетингового слоя.
- Скриншоты могут отличаться на разных машинах (известная особенность Detox) — это важно при сравнении в CI, но безвредно для ассетов магазина.
Вариант 3 — ручной захват (проще всего, и недооценён)
Открываешь iOS Simulator или Android-эмулятор, вручную доводишь приложение до каждого нужного экрана и захватываешь кадр. На iOS Cmd-S в Simulator сохраняет PNG правильного размера на рабочий стол; xcrun simctl io booted screenshot home.png делает то же самое из терминала и легко поддаётся несложному скриптингу. На Android кнопка скриншота в эмуляторе или adb exec-out screencap -p > home.png захватывает экран. Физическое устройство тоже подходит — сними скриншот, затем перенеси файлы через AirDrop или иным способом.
Этот вариант слишком быстро отвергают. Нулевая настройка, никогда не ломается в CI — потому что CI нет, — и для приложения с горсткой релизов в год это действительно самый быстрый путь к набору исходных кадров. Минус очевиден и реален: всё вручную, само по себе ничего не пересоздаётся, и если изменить экран — скриншоты устаревают до следующего прогона. Для карусели из пяти экранов это десять минут работы на релиз — дешевле, чем поддерживать тестовую автоматизацию, которую запускаешь дважды в год.
То, о чём все забывают: компоновка и локализация
Вот что объединяет все три варианта: каждый из них даёт сырые скриншоты приложения, а сырые скриншоты — не то, что конвертирует в магазине. Карусель App Store, которая действительно двигает установки, включает рамку устройства вокруг экрана, однострочную подпись сверху с объяснением преимущества, фон — не белый из приложения, и единый стиль по всем пяти панелям. Ни один из инструментов захвата выше этого не даёт — они останавливаются на голом кадре. Это не недостаток; это просто другая работа.
Именно здесь в схему вписывается Mokbi, и стоит чётко обозначить границу: он не захватывает исходные скриншоты — это делают симулятор, устройство или Fastlane/Detox выше. Mokbi отвечает за маркетинговую компоновку и локализацию, которые идут следующим шагом. Загружаешь сырые кадры в браузерный редактор, оборачиваешь в настоящие рамки устройств, добавляешь подписи, выстраиваешь мультипанельную карусель, затем одним кликом переводишь подписи на 50 языков и пакетно экспортируешь во всех размерах магазина. Дизайн бесплатен с водяным знаком предпросмотра; безлимитный экспорт и публикация доступны по подписке — Solo €29.99/mo (1 приложение) или Studio €49.99/mo (до 5 приложений), без разовой покупки. Инструмент вписывается органично, потому что решает задачу, которую твой пайплайн захвата даже не пытается решить: превратить папку PNG в локализованную карусель, готовую к публикации, без открытия Photoshop и ручного изменения размеров для 50 языков.
Реалистичный совмещённый воркфлоу
- Захвати исходные кадры. Выбери один вариант: Fastlane (snapshot + screengrab) в CI для частых релизов, Detox — если e2e-тесты уже есть, или ручной захват из симулятора для редких релизов. Результат: папка сырых PNG на экран и на устройство.
- Компоновка, подписи, рамки. Загрузи сырые кадры в браузерный редактор. Добавь рамки устройств, напиши подписи с преимуществами, собери карусель из пяти панелей, выбери фон.
- Локализация. Одним кликом переведи подписи на 50 языков, затем вручную проверь те локали, которые важны для тебя больше всего.
- Пакетный экспорт. Экспортируй все локали во всех нужных размерах для App Store Connect и Google Play за один проход.
- Замена при следующем релизе. Перезахвати изменившиеся кадры (перезапусти Fastlane/Detox или сделай вручную), открой сохранённый проект, замени скриншоты, переэкспортируй. Работа с подписями и переводами уже сделана.
Когда можно обойтись без автоматизации
Если выпускаешь один-три релиза в год — а это описывает большинство инди React Native приложений — затраты на настройку Fastlane или Detox почти никогда не окупаются. Потратишь день на подключение XCUITest и танец с Metro bundler, чтобы сэкономить десять минут ручного захвата дважды в год. Математика не сходится. Захватывай вручную из симулятора, компонуй и локализуй в браузере — и уложишься в меньшее суммарное время, чем заняла бы однократная настройка автоматизации.
Автоматизация оправдывает себя, когда релизы идут еженедельно или ежедневно, когда расхождение скриншотов становится повторяющейся проблемой, или когда у тебя портфолио приложений и стоимость захвата на приложение множится. На таком масштабе Fastlane в CI (или Detox, если он уже в стеке) — правильный выбор для шага захвата — и его всё равно нужно совмещать с браузерным инструментом компоновки для маркетингового слоя, потому что ни один пайплайн захвата не даёт готовой карусели.
Перед любым экспортом стоит уточнить целевые параметры: размеры скриншотов App Store, которые нужно загружать, и требования к скриншотам App Store, из-за которых отклоняют заявки. Разобраться с этим один раз избавит от лишнего раунда с App Review.