Expo — платформа для React Native разработки

19 июня 2026
Автор

Олег Марков

Введение

Если вы работаете с React Native или только планируете начать, Expo — это первое, с чем вы столкнётесь. Это комплексная платформа, которая значительно упрощает разработку, сборку и публикацию мобильных приложений. Однако за простотой скрывается мощный инструментарий, который важно понимать глубоко, чтобы делать осознанный выбор в пользу Expo или чистого React Native.

В этой статье мы разберём всё, что нужно знать о Expo: от базовых концепций и быстрого старта до EAS Build, Expo Router и принципов OTA-обновлений.

Что такое Expo и зачем он нужен

Expo — это open source платформа и набор инструментов, построенных поверх React Native. Он предоставляет:

  • Унифицированный инструмент разработки — CLI, эмулятор в браузере, мобильный клиент для тестирования
  • Готовые API и компоненты — Expo SDK с модулями для камеры, геолокации, уведомлений и многого другого
  • Облачные сервисы — EAS (Expo Application Services) для сборки, публикации и обновлений
  • Файловую маршрутизацию — Expo Router для навигации в стиле Next.js

Основная идея Expo — убрать сложность нативной настройки и позволить разработчику сосредоточиться на написании JavaScript/TypeScript кода. Вместо того чтобы разбираться с Xcode, Android Studio, Gradle и CocoaPods, вы просто пишете код, а Expo берёт на себя остальное.

Expo — это отличный выбор для большинства проектов, но для его эффективного использования важно понимать, как работает React Native и мобильная разработка в целом. Если вы хотите получить системные знания — приходите на курс React Native и Expo Router. На курсе 184 урока и 11 упражнений, AI-тренажёры для практики 24/7, решение задач с живым ревью наставника, еженедельные встречи с менторами.

Основные возможности Expo

Expo Go — мгновенное тестирование

Expo Go — это мобильное приложение из App Store и Google Play, которое позволяет запускать ваш код без сборки нативного приложения. После запуска npx expo start вы получаете QR-код, который сканируете в Expo Go, и ваше приложение появляется на телефоне за секунды.

# Запуск девелоперского сервера
npx expo start

# Expo Go автоматически подхватит изменения при сохранении файлов

Ограничение Expo Go: он работает только с пакетами, включёнными в Expo SDK. Если вам нужен кастомный нативный модуль, Expo Go не подойдёт — нужно будет собрать development build.

Development Build — замена Expo Go

Development Build — это ваше собственное приложение с встроенным expo-dev-client. Оно ведёт себя как Expo Go, но поддерживает любые нативные библиотеки:

# Установка expo-dev-client
npx expo install expo-dev-client

# Сборка development build через EAS
eas build --profile development --platform android

Expo SDK — готовые модули для нативных функций

Expo SDK — набор модулей для работы с нативными возможностями устройства. Все модули тестируются совместно и обновляются синхронно:

# Установка нужных модулей
npx expo install expo-camera expo-location expo-notifications

Основные модули SDK:

Модуль Функциональность
expo-camera Камера, сканирование QR/штрихкодов
expo-location GPS и геолокация
expo-notifications Push-уведомления
expo-image-picker Выбор фото и видео из галереи
expo-file-system Работа с файловой системой
expo-secure-store Безопасное хранение данных
expo-av Аудио и видео воспроизведение
expo-sensors Акселерометр, гироскоп, барометр
expo-font Загрузка кастомных шрифтов
expo-splash-screen Управление сплэш-экраном

Пример использования камеры:

import { CameraView, useCameraPermissions } from 'expo-camera';
import { Button, Text, View } from 'react-native';

export default function CameraScreen() {
  const [permission, requestPermission] = useCameraPermissions();

  if (!permission) {
    // Разрешения ещё загружаются
    return <View />;
  }

  if (!permission.granted) {
    return (
      <View>
        <Text>Нужен доступ к камере</Text>
        <Button title="Разрешить" onPress={requestPermission} />
      </View>
    );
  }

  return (
    <CameraView style={{ flex: 1 }} facing="back">
      {/* Контент поверх камеры */}
    </CameraView>
  );
}

Managed Workflow vs Bare Workflow

Это принципиальный выбор, который определяет архитектуру вашего проекта.

Managed Workflow

В Managed Workflow Expo полностью управляет нативным кодом. У вас нет папок android/ и ios/ в репозитории. Конфигурация идёт через app.json или app.config.js:

{
  "expo": {
    "name": "My App",
    "slug": "my-app",
    "version": "1.0.0",
    "icon": "./assets/icon.png",
    "splash": {
      "image": "./assets/splash.png",
      "backgroundColor": "#ffffff"
    },
    "ios": {
      "bundleIdentifier": "com.company.myapp",
      "supportsTablet": true
    },
    "android": {
      "package": "com.company.myapp",
      "adaptiveIcon": {
        "foregroundImage": "./assets/adaptive-icon.png",
        "backgroundColor": "#ffffff"
      }
    },
    "plugins": [
      ["expo-camera", { "cameraPermission": "Нужен доступ к камере" }]
    ]
  }
}

Преимущества Managed Workflow:

  • Нет нативного кода в репозитории — чище, проще
  • Обновления Expo SDK минимальны — меняете версию в package.json
  • Конфигурация нативных функций через Config Plugins
  • OTA-обновления работают из коробки

Ограничения Managed Workflow:

  • Только модули из Expo SDK или совместимые с ним
  • Нельзя добавить произвольный нативный код напрямую
  • Зависимость от цикла обновлений Expo SDK

Bare Workflow

В Bare Workflow у вас есть полный доступ к нативному коду — папки android/ и ios/ присутствуют в проекте. Вы можете использовать любые React Native библиотеки и вносить любые нативные изменения, но берёте на себя ответственность за управление нативными зависимостями.

# Создание проекта в Bare Workflow
npx create-expo-app my-app --template bare-minimum

# Или переход из Managed (устаревший способ)
npx expo prebuild

Команда expo prebuild генерирует нативные папки из вашей конфигурации в app.config.js. Это ключевая особенность — вы можете работать в стиле Managed, но при необходимости "овеществить" нативный код.

Когда выбирать Bare Workflow:

  • Нужны кастомные нативные модули, которых нет в Expo SDK
  • Требуется глубокая интеграция с нативными SDK (например, сложные платёжные системы)
  • Нужен полный контроль над нативными настройками

Expo Router для навигации

Expo Router — это файловая система маршрутизации для React Native, работающая по принципу Next.js. Структура папок в app/ определяет маршруты приложения:

app/
├── _layout.tsx       # Корневой layout
├── index.tsx         # Маршрут "/" (главный экран)
├── (tabs)/
│   ├── _layout.tsx   # Layout для tab-навигации
│   ├── home.tsx      # Маршрут "/home"
│   └── profile.tsx   # Маршрут "/profile"
├── product/
│   ├── [id].tsx      # Динамический маршрут "/product/123"
│   └── index.tsx     # Маршрут "/product"
└── modal.tsx         # Модальный экран

Пример layout с tab-навигацией:

// app/(tabs)/_layout.tsx
import { Tabs } from 'expo-router';
import { MaterialIcons } from '@expo/vector-icons';

export default function TabsLayout() {
  return (
    <Tabs>
      <Tabs.Screen
        name="home"
        options={{
          title: 'Главная',
          tabBarIcon: ({ color, size }) => (
            <MaterialIcons name="home" size={size} color={color} />
          ),
        }}
      />
      <Tabs.Screen
        name="profile"
        options={{
          title: 'Профиль',
          tabBarIcon: ({ color, size }) => (
            <MaterialIcons name="person" size={size} color={color} />
          ),
        }}
      />
    </Tabs>
  );
}

Навигация в Expo Router:

import { router, useLocalSearchParams } from 'expo-router';

// Переход на экран
router.push('/product/123');

// Замена текущего маршрута
router.replace('/home');

// Назад
router.back();

// Получение параметров маршрута
function ProductScreen() {
  const { id } = useLocalSearchParams<{ id: string }>();
  return <Text>Продукт: {id}</Text>;
}

Expo Router поддерживает Deep Linking из коробки — маршруты автоматически становятся Universal Links для iOS и App Links для Android.

EAS — Expo Application Services

EAS — это набор облачных сервисов для профессиональной разработки с Expo. Он включает три основных продукта.

EAS Build

EAS Build — облачный сервис для сборки нативных приложений. Вы не собираете приложение локально — EAS делает это на своих серверах:

# Установка EAS CLI
npm install -g eas-cli

# Авторизация в Expo
eas login

# Инициализация EAS в проекте
eas build:configure

Конфигурация в eas.json:

{
  "cli": {
    "version": ">= 5.0.0"
  },
  "build": {
    "development": {
      "developmentClient": true,
      "distribution": "internal"
    },
    "preview": {
      "distribution": "internal",
      "android": {
        "buildType": "apk"
      }
    },
    "production": {
      "autoIncrement": true
    }
  },
  "submit": {
    "production": {
      "android": {
        "serviceAccountKeyPath": "./google-services-key.json",
        "track": "production"
      },
      "ios": {
        "appleId": "your@email.com",
        "ascAppId": "1234567890"
      }
    }
  }
}

Запуск сборки:

# Сборка для Android (production)
eas build --platform android

# Сборка для iOS (production)
eas build --platform ios

# Сборка для обеих платформ
eas build --platform all

# Сборка preview (APK для тестирования)
eas build --profile preview --platform android

Преимущества EAS Build:

  • Не нужен macOS для сборки iOS приложений
  • Подписывает приложения автоматически
  • Кеширует зависимости для ускорения
  • Интегрируется с CI/CD

EAS Submit

EAS Submit автоматизирует загрузку приложения в App Store и Google Play:

# Загрузка последней сборки в магазины
eas submit --platform android
eas submit --platform ios

# Указание конкретной сборки
eas submit --platform android --id <build-id>

EAS Update — OTA обновления

EAS Update позволяет обновлять JavaScript-код приложения без публикации новой версии в магазины. Это работает потому, что React Native выполняет JS-код динамически:

# Установка модуля
npx expo install expo-updates

# Публикация обновления
eas update --branch production --message "Исправлен баг с авторизацией"

Конфигурация обновлений в app.json:

{
  "expo": {
    "updates": {
      "url": "https://u.expo.dev/your-project-id",
      "checkAutomatically": "ON_LOAD",
      "fallbackToCacheTimeout": 0
    },
    "runtimeVersion": {
      "policy": "appVersion"
    }
  }
}

Программное управление обновлениями:

import * as Updates from 'expo-updates';

async function checkForUpdates() {
  try {
    const update = await Updates.checkForUpdateAsync();

    if (update.isAvailable) {
      await Updates.fetchUpdateAsync();
      // Применяем обновление при следующем запуске
      await Updates.reloadAsync();
    }
  } catch (error) {
    console.log('Ошибка при проверке обновлений:', error);
  }
}

Ограничения OTA-обновлений:

  • Нельзя обновить нативный код (Java/Kotlin/Swift/ObjC)
  • Нельзя добавить новые нативные зависимости
  • Обновление JavaScript, ассетов (картинки, шрифты) — можно

Преимущества Expo

Скорость разработки

  • Нет нужды настраивать Xcode/Android Studio для базовой разработки
  • Expo Go позволяет видеть изменения мгновенно
  • Hot reloading работает из коробки

Экосистема

  • Более 200 готовых нативных модулей в Expo SDK
  • Все модули тестируются совместно — нет конфликтов версий
  • Регулярные обновления с поддержкой новых версий React Native

Инфраструктура

  • EAS Build — сборка без локального окружения
  • EAS Submit — автоматическая публикация в магазины
  • OTA-обновления — быстрые фиксы без ревью магазина

Expo Router

  • Файловая маршрутизация как в Next.js
  • Типобезопасные маршруты
  • Universal Links из коробки
  • Tab-навигация, stack-навигация, модалы — всё конфигурируется через файловую структуру

TypeScript

  • Полная поддержка TypeScript из коробки
  • Типы для всех модулей SDK

Недостатки Expo

Зависимость от Expo SDK В Managed Workflow вы ограничены тем, что поддерживает Expo SDK. Если нужна библиотека с нативным кодом, которой нет в SDK — придётся переходить в Bare Workflow.

Размер приложения Expo SDK включает много предустановленных модулей, что увеличивает размер итогового приложения. В Managed Workflow нет возможности убрать неиспользуемые нативные модули без Bare Workflow.

Задержка обновлений React Native Expo SDK обновляется после выхода новой версии React Native — обычно с задержкой в несколько месяцев. Если нужны самые свежие возможности RN, Expo может не успевать.

Зависимость от облачной инфраструктуры EAS Build — платный сервис (с бесплатным тарьфом с ограничениями). Команды с большим количеством сборок платят за облачное время сборки.

Сложность при глубокой нативной интеграции Для некоторых случаев (специализированные SDK для устройств, сложные платёжные системы, Bluetooth Low Energy) интеграция в Expo сложнее, чем в чистом React Native.

Когда выбирать Expo, когда чистый React Native

Выбирайте Expo если:

  • Стартуете новый проект — Expo даст преимущество в скорости старта
  • Команда не имеет опыта с нативной разработкой (Xcode/Android Studio)
  • Нужны стандартные нативные функции: камера, геолокация, уведомления, авторизация
  • Важно OTA-обновления для быстрого деплоя фиксов
  • Нет выделенного iOS-разработчика — EAS Build позволяет собирать iOS без Mac
  • Небольшая или средняя команда, важна скорость разработки

Выбирайте чистый React Native если:

  • Уже существующий проект с большим количеством кастомного нативного кода
  • Нужна глубокая интеграция с проприетарными нативными SDK
  • Критична минимальная размер приложения и максимальный контроль над бандлом
  • Требуются возможности, которые Expo SDK не покрывает
  • Команда имеет сильный опыт в iOS/Android разработке

Компромисс: Bare Workflow Bare Workflow даёт вам лучшее из двух миров — вы используете инструменты Expo (EAS Build, OTA-обновления, Config Plugins), но имеете полный доступ к нативному коду. Большинство продакшн-проектов, которые начинают с Managed Workflow, в итоге переходят к Bare Workflow по мере роста.

Быстрый старт и базовые команды

Создание нового проекта

# Новый проект с Expo Router (рекомендуется)
npx create-expo-app my-app

# С конкретным шаблоном
npx create-expo-app my-app --template tabs

# Bare Workflow
npx create-expo-app my-app --template bare-minimum

Основные команды разработки

# Запуск девелоперского сервера
npx expo start

# Запуск на конкретной платформе
npx expo start --android
npx expo start --ios

# Очистка кеша
npx expo start --clear

# Установка пакетов (используйте expo install вместо npm install)
npx expo install expo-camera
npx expo install react-native-reanimated

# Проверка совместимости пакетов
npx expo doctor

Команды EAS

# Сборка development build
eas build --profile development --platform android

# Сборка для production
eas build --platform all

# Публикация OTA-обновления
eas update --branch production --message "Fix"

# Отправка в магазины
eas submit --platform all

# Просмотр истории сборок
eas build:list

Структура проекта

Типичный Expo проект с Expo Router выглядит так:

my-app/
├── app/                    # Маршруты (Expo Router)
│   ├── _layout.tsx         # Корневой layout
│   ├── (tabs)/             # Группа вкладок
│   │   ├── _layout.tsx
│   │   ├── index.tsx
│   │   └── explore.tsx
│   └── modal.tsx
├── assets/                 # Статические файлы
│   ├── fonts/
│   └── images/
├── components/             # Переиспользуемые компоненты
│   ├── ui/
│   └── ...
├── hooks/                  # Кастомные хуки
├── constants/              # Константы (цвета, размеры)
├── app.json                # Конфигурация Expo
├── eas.json                # Конфигурация EAS
├── babel.config.js         # Конфигурация Babel
├── tsconfig.json           # TypeScript конфигурация
└── package.json

Конфигурационные файлы:

// babel.config.js
module.exports = function(api) {
  api.cache(true);
  return {
    presets: ['babel-preset-expo'],
    plugins: ['expo-router/babel']
  };
};
// tsconfig.json
{
  "extends": "expo/tsconfig.base",
  "compilerOptions": {
    "strict": true,
    "paths": {
      "@/*": ["./*"]
    }
  }
}

Заключение

Expo — это зрелая платформа, которая за годы развития стала стандартом для большинства новых проектов на React Native. Managed Workflow даёт быстрый старт и простоту поддержки, Bare Workflow — гибкость и контроль. EAS Build, Submit и Update закрывают весь цикл CI/CD без необходимости настраивать собственную инфраструктуру. Expo Router привносит знакомую файловую маршрутизацию в мобильную разработку.

Правильный выбор между Expo и чистым React Native зависит от требований проекта, опыта команды и нативных зависимостей. Для большинства новых проектов Expo в Managed Workflow — это оптимальная отправная точка, от которой всегда можно перейти к Bare Workflow при необходимости.

Чтобы освоить Expo и React Native на практике, включая работу с Expo Router, EAS и нативными модулями, приходите на курс React Native и Expo Router. В первых 3 модулях доступно бесплатное содержание — можно начать прямо сейчас.

Часто задаваемые вопросы

Можно ли использовать Expo с существующим React Native проектом?

Да, можно подключить отдельные пакеты Expo SDK к существующему RN проекту, но полноценные возможности Expo (EAS Build, Expo Router, Config Plugins) лучше использовать с проектами, созданными через create-expo-app. Частичная интеграция возможна, но потребует ручной настройки.

Expo Router или React Navigation — что выбрать?

Expo Router работает поверх React Navigation и добавляет файловую маршрутизацию. Если начинаете новый проект с Expo — используйте Expo Router: он проще в конфигурации и поддерживает Deep Linking из коробки. React Navigation по-прежнему актуален для Bare Workflow и проектов, где нужна нестандартная структура навигации.

Как работает OTA-обновление, если пользователь не открывает приложение?

OTA-обновление загружается при следующем запуске приложения. Если пользователь редко открывает приложение, обновление всё равно применится при следующем запуске. Вы можете настроить поведение: применять обновление сразу (reloadAsync()) или при следующем запуске.

Нужен ли аккаунт Expo для использования Expo CLI?

Для базовой разработки с Expo Go аккаунт не обязателен. Для EAS Build, EAS Submit и EAS Update — нужна регистрация на expo.dev. Бесплатный план включает ограниченное количество сборок в месяц.

Как управлять разными окружениями (dev/staging/production) в Expo?

Используйте app.config.js вместо app.json для динамической конфигурации, переменные окружения через process.env и профили в eas.json. Каждый профиль EAS может иметь свои переменные окружения и настройки сборки.

// app.config.js
export default ({ config }) => {
  const isProduction = process.env.APP_ENV === 'production';

  return {
    ...config,
    name: isProduction ? 'My App' : 'My App (Dev)',
    slug: 'my-app',
    extra: {
      apiUrl: isProduction
        ? 'https://api.production.com'
        : 'https://api.staging.com',
    },
  };
};
Стрелочка влевоНастройка и использование плагина Gradle на React Native

Постройте личный план изучения React-native до уровня Middle — бесплатно!

React-native — часть карты развития Mobile

  • step100+ шагов развития
  • lessons30 бесплатных лекций
  • lessons300 бонусных рублей на счет

Бесплатные лекции

Все гайды по React-native

Работа со ScrollView в React NativeОсновные компоненты React NativeРабота с видео в React NativeКак реализовать аудиоплеер на React NativeНастройка и использование input и textinput в React NativeИнтеграция видео плеера в приложение на React NativeИспользование выпадающих списков в React NativeСоздание и настройка native module на React NativeКак создать модальные окна в React NativeРабота с изображениями в React NativeОтображение списков данных в React NativeГайд по файловой системе в React NativeИнтеграция камеры в приложение на React NativeСоздание интерактивных кнопок в React NativeНативные модули в React Native
Стили в React Native
Стили в React NativeНавигация в React Native (react-navigation)Как использовать векторные иконки в React Native5 популярных библиотек UI компонентов React NativeСоздание и использование tabs в React NativeРуководство по стилизации компонентов в React NativeОптимизация переходов между экранами в React NativeАдаптация safe area context на React NativeОбзор библиотек для навигации в React NativeСоздание сложных анимаций (reanimated) на React NativeИспользование библиотеки стилей Paper в React NativeРуководство по navigation в React NativeОптимизация отображения списков в React NativeКак реализовать linking на React NativeГде искать elements для приложения на React NativeГайд по UI-китам для React NativeРабота с цветами в React Native
Работа с компонентом view в React NativeРабота с компонентом text в React NativeС чего начать разработку проекта на React NativeУстановка и настройка React Native SDKНастройка React Native для работы с iOSПошаговая инструкция по установке React NativeЧто такое React Native Expo и зачем он нуженГайд по использованию React Native CLIReact Native - основыНастройка Android Studio на React NativeНастройка React Native для работы с AndroidЧто такое React Native Введение для начинающихНастройка и использование плагина Gradle на React NativeExpo — платформа для React Native разработки
Открыть базу знаний

Лучшие курсы по теме

изображение курса

React Native и Expo Router

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Основы JavaScript

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее

Отправить комментарий