Нативная разработка — это два отдельных приложения: Kotlin с Jetpack Compose для Android и Swift со SwiftUI для iOS, с полным доступом ко всем API платформы. React Native (обычно вместе с Expo) позволяет писать одно приложение на TypeScript в модели React, а на экране оказываются настоящие нативные компоненты. Flutter тоже даёт один код, но на Dart, и рисует интерфейс собственным движком; выбор между ними определяют требования к API устройства, состав команды и то, сколько платформенного кода вы готовы поддерживать.
После материала вы сможете
- сравнить Kotlin/Compose, Swift/SwiftUI, React Native с Expo и Flutter по языку, способу отрисовки интерфейса, доступу к API устройства и общему коду
- объяснить, почему React Native не «сайт в обёртке» и чем его компоненты
ViewиTextотличаются от<div>и<p> - пройти дерево решений и обосновать выбор стека под требования и команду
- перечислить шаги сборки и публикации, общие для всех стеков, включая сборку iOS и хранение ключей подписи
Что знать заранее
Содержание
Сначала: нужно ли приложение из стора
Прежде чем сравнивать фреймворки, стоит проверить, нужно ли вообще устанавливаемое приложение. MDN определяет PWA (progressive web app) как приложение на веб-технологиях, которое работает на разных платформах из одной кодовой базы, устанавливается на устройство, умеет работать офлайн и интегрироваться с системой. Если сценарий укладывается в возможности браузера, PWA проще в выпуске и обновлении. Бизнес-сторону этого выбора — модерацию, каналы привлечения, этапность — мы разобрали в статье «PWA или мобильное приложение»; здесь — инженерный угол: что именно меняется в коде, инструментах и команде.
Инженерные признаки того, что веба будет мало: приложение должно жить в App Store и Google Play; нужны API, к которым браузер не даёт доступа или даёт с ограничениями на конкретной платформе; важна работа в фоне, тесная интеграция с системой (виджеты, общий доступ, биометрия, платежи платформы); нужен плавный сложный интерфейс с жестами и анимацией на слабых устройствах.
Нативно: Kotlin с Compose и Swift со SwiftUI
Нативное приложение пишется на основном языке платформы её же инструментами. Для Android это Kotlin: Google с 2019 года развивает платформу по принципу Kotlin-first и рекомендует начинать новые приложения с него, сохраняя поддержку Java. Интерфейс строят на Jetpack Compose — документация Android называет его рекомендуемым современным набором инструментов для нативного UI: вы описываете интерфейс, а при изменении состояния Compose обновляет его сам. Среда — Android Studio.
Для iOS это Swift и SwiftUI — декларативный фреймворк Apple для всех её платформ, с живым предпросмотром в Xcode. SwiftUI можно внедрять постепенно рядом с более старым UIKit. Xcode — набор инструментов Apple для разработки, тестирования и распространения приложений, и работает он на Mac.
Сильные стороны
- Новые API системы доступны сразу, без ожидания обёрток от фреймворка
- Интерфейс и поведение полностью соответствуют платформе
- Официальная документация, примеры и инструменты профилирования — от производителя ОС
Цена
- Два приложения, два языка, две кодовые базы — каждую функцию делают дважды
- Нужны разработчики под каждую платформу или люди, знающие обе
- Синхронизировать поведение и релизы двух версий — отдельная работа
Промежуточный вариант — Kotlin Multiplatform. Google официально поддерживает его для общего кода бизнес-логики между Android и iOS, а Compose Multiplatform от JetBrains позволяет при желании разделять и интерфейс. Это подход для команды, которая уже пишет на Kotlin и хочет перестать дублировать логику, не отказываясь от нативного UI.
React Native и Expo: React-модель и нативные компоненты
React Native позволяет писать мобильное приложение на JavaScript или TypeScript в той же модели, что и React: компоненты, props, состояние, хуки. Принципиальное отличие от веба — нет DOM и HTML. Вместо <div> и <p> используются компоненты View и Text, и во время работы React Native создаёт для них настоящие представления Android и iOS. Это не сайт в обёртке: на экране — системные элементы интерфейса.
View
- Android
ViewGroup- iOS
UIView- Ближайший аналог в вебе
<div>без прокрутки
Text
- Android
TextView- iOS
UITextView- Ближайший аналог в вебе
<p>
Image
- Android
ImageView- iOS
UIImageView- Ближайший аналог в вебе
<img>
ScrollView
- Android
ScrollView- iOS
UIScrollView- Ближайший аналог в вебе
<div>с прокруткой
TextInput
- Android
EditText- iOS
UITextField- Ближайший аналог в вебе
<input type="text">
С версии 0.76 в React Native по умолчанию включена новая архитектура: асинхронный «мост» между JavaScript и нативным кодом заменён на JSI (JavaScript Interface) — прямые вызовы без сериализации данных. Она же поддерживает конкурентные возможности React 18 и новее. Документация честно оговаривает, что сама по себе новая архитектура не гарантирует ускорения: выигрыш зависит от кода приложения.
Сама команда React Native рекомендует начинать новые приложения с фреймворка, и в первую очередь называет Expo: он даёт файловую маршрутизацию, стандартную библиотеку нативных модулей и плагины, которые меняют нативный код без ручного редактирования проектов Android и iOS. На момент проверки актуален Expo SDK 57 — он построен на React Native 0.86 и React 19.2.
Flutter и Dart: собственный движок отрисовки
Flutter решает ту же задачу «один код — две платформы» иначе. Вместо системных элементов интерфейса он рисует всё сам: у Flutter собственные реализации каждого элемента управления на Dart, включая аналоги переключателей iOS и Android. Отрисовкой занимается движок на C++ с рендерером Impeller, который поставляется вместе с приложением; на iOS Impeller — единственный поддерживаемый рендерер, на Android он включён по умолчанию с API 29.
Код пишется на Dart. Во время разработки приложение работает в виртуальной машине с горячей перезагрузкой (hot reload) — изменения видны без полной пересборки и без потери состояния. Для релиза Flutter компилирует код напрямую в машинные инструкции. К API платформы Flutter обращается через platform channels — канал сообщений между Dart и нативным кодом — или через FFI для C-библиотек.
Сравнение по инженерным критериям
Язык
- Нативно (Kotlin / Swift)
- Kotlin и Swift — два языка
- React Native + Expo
- TypeScript / JavaScript
- Flutter
- Dart
Как появляется интерфейс
- Нативно (Kotlin / Swift)
- Системные фреймворки: Compose, SwiftUI
- React Native + Expo
- Компоненты React → нативные представления платформы
- Flutter
- Собственные виджеты, рисует движок Impeller
Общий код Android и iOS
- Нативно (Kotlin / Swift)
- Нет (или логика через Kotlin Multiplatform)
- React Native + Expo
- Большая часть приложения
- Flutter
- Большая часть приложения
Новые API системы
- Нативно (Kotlin / Swift)
- Сразу после выхода SDK
- React Native + Expo
- Через модули Expo и сообщества или свой нативный модуль
- Flutter
- Через плагины или свой код в platform channels
Цикл разработки
- Нативно (Kotlin / Swift)
- Сборка и превью в Android Studio / Xcode
- React Native + Expo
- Быстрое обновление кода через Metro, Expo Go
- Flutter
- Hot reload в виртуальной машине Dart
Веб из того же кода
- Нативно (Kotlin / Swift)
- Нет
- React Native + Expo
- Да, через React Native for Web в Expo
- Flutter
- Да, Flutter web
Кого искать в команду
- Нативно (Kotlin / Swift)
- Android- и iOS-разработчиков
- React Native + Expo
- React/TypeScript-разработчиков с мобильным опытом
- Flutter
- Flutter/Dart-разработчиков
Производительность в таблицу намеренно не вынесена одной цифрой: все три подхода в итоге исполняют на устройстве скомпилированный нативный код движка, а узкие места обычно в конкретном приложении — длинные списки, тяжёлые изображения, лишние перерисовки. Сравнивать стоит прототип вашего самого тяжёлого экрана на реальном среднем телефоне, а не общие бенчмарки.
Сборка и публикация: общее для всех стеков
Как бы ни было написано приложение, на выходе это пакет для Android и пакет для iOS, которые подписываются ключами разработчика и проходят проверку магазинов. Здесь различия между стеками меньше, чем кажется.
Аккаунты разработчика
Google Play Console и Apple Developer Program оформляются на компанию-владельца продукта, а не на подрядчика.
Сборка iOS
Документация React Native прямо говорит: для сборки проектов с нативным кодом под iOS нужен Mac. Облачные сервисы, например EAS Build у Expo, собирают iOS-версию на своих macOS-машинах.
Подпись
Ключи подписи Android и сертификаты iOS — критичные секреты: их теряют один раз и надолго. EAS Build умеет хранить и выпускать их сам, при нативной сборке за этим следит команда.
Проверка магазином
Требования App Store и Google Play одинаковы для всех стеков: фреймворк их не обходит.
Обновления
Новую версию пользователи получают через магазин. Для JavaScript-кода Expo предлагает обновления без пересборки (EAS Update) в рамках правил магазинов.
Как выбрать: дерево решений
Ниже — порядок вопросов, который мы используем как отправную точку. Это не правило, а способ не пропустить важное: ответ «да» на ранний вопрос обычно весит больше, чем все следующие.
Хватит ли браузера?
Если сценарий — каталог, запись, личный кабинет и магазины приложений не обязательны, начните с PWA или адаптивного веб-приложения.
Продукт держится на одной платформе или на глубокой интеграции с ней?
Только iOS, виджеты, Apple Watch, CarPlay, сложная работа с камерой или Bluetooth в фоне — нативная разработка снимает риск ожидания обёрток.
Уже есть веб-продукт и команда на React/TypeScript?
React Native с Expo позволяет переиспользовать язык, подходы, типы и часть бизнес-логики, а Expo закрывает типовую нативную инфраструктуру.
Нужен одинаковый фирменный интерфейс на всех платформах и команда готова к Dart?
Flutter даёт полный контроль над каждым пикселем за счёт собственного рендеринга.
Есть сильная Android-команда на Kotlin?
Рассмотрите Kotlin Multiplatform: общая логика, нативный интерфейс на каждой платформе.
- Выписаны API устройства, без которых продукт не работает, и проверена их поддержка в выбранном стеке
- Понятно, кто в команде будет поддерживать код через два года и легко ли найти замену
- Определено, нужен ли веб из той же кодовой базы
- Самый тяжёлый экран проверен прототипом на реальном недорогом телефоне
- Решено, где и кем собирается iOS-версия и где хранятся ключи подписи
Дальше по траектории: первое приложение на React Native и Expo — от create-expo-app до экрана со стилями, затем навигация в Expo Router. Для Flutter — отдельный урок о Dart и виджетах.
