· Workflow · 9 мин. чтения

Скриншоты App Store для React Native приложений (2026)

Скриншоты App Store для React Native приложений (2026)
TL;DR. React Native не даёт никакого встроенного пайплайна для скриншотов. Реальные варианты захвата исходных кадров: Fastlane (XCUITest на iOS, screengrab/Espresso на Android), Detox (создан специально для RN и проще всего в освоении) или просто ручной захват из симулятора. Любой из них даёт только сырые скриншоты приложения — превратить их в готовую карусель с подписями, рамками устройств и локализованными вариантами — отдельный маркетинговый шаг. Для большинства команд, выпускающих несколько релизов в год, ручной захват плюс браузерная компоновка быстрее, чем день настройки Fastlane.

Вот что никто не говорит, когда ты публикуешь первое 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 языков.

Реалистичный совмещённый воркфлоу

  1. Захвати исходные кадры. Выбери один вариант: Fastlane (snapshot + screengrab) в CI для частых релизов, Detox — если e2e-тесты уже есть, или ручной захват из симулятора для редких релизов. Результат: папка сырых PNG на экран и на устройство.
  2. Компоновка, подписи, рамки. Загрузи сырые кадры в браузерный редактор. Добавь рамки устройств, напиши подписи с преимуществами, собери карусель из пяти панелей, выбери фон.
  3. Локализация. Одним кликом переведи подписи на 50 языков, затем вручную проверь те локали, которые важны для тебя больше всего.
  4. Пакетный экспорт. Экспортируй все локали во всех нужных размерах для App Store Connect и Google Play за один проход.
  5. Замена при следующем релизе. Перезахвати изменившиеся кадры (перезапусти Fastlane/Detox или сделай вручную), открой сохранённый проект, замени скриншоты, переэкспортируй. Работа с подписями и переводами уже сделана.

Когда можно обойтись без автоматизации

Если выпускаешь один-три релиза в год — а это описывает большинство инди React Native приложений — затраты на настройку Fastlane или Detox почти никогда не окупаются. Потратишь день на подключение XCUITest и танец с Metro bundler, чтобы сэкономить десять минут ручного захвата дважды в год. Математика не сходится. Захватывай вручную из симулятора, компонуй и локализуй в браузере — и уложишься в меньшее суммарное время, чем заняла бы однократная настройка автоматизации.

Автоматизация оправдывает себя, когда релизы идут еженедельно или ежедневно, когда расхождение скриншотов становится повторяющейся проблемой, или когда у тебя портфолио приложений и стоимость захвата на приложение множится. На таком масштабе Fastlane в CI (или Detox, если он уже в стеке) — правильный выбор для шага захвата — и его всё равно нужно совмещать с браузерным инструментом компоновки для маркетингового слоя, потому что ни один пайплайн захвата не даёт готовой карусели.

Перед любым экспортом стоит уточнить целевые параметры: размеры скриншотов App Store, которые нужно загружать, и требования к скриншотам App Store, из-за которых отклоняют заявки. Разобраться с этим один раз избавит от лишнего раунда с App Review.

Что читать дальше

Открыть редактор →