← назад к разделу

Представьте: у вас уже есть веб-приложение на React. Его открывают в браузере — всё работает. Но продукт просят выложить в App Store и Google Play. Переписывать на Swift и Kotlin? Это месяцы работы и вторая команда разработчиков.

Capacitor решает эту проблему иначе: он берёт уже готовое веб-приложение, оборачивает его в нативный контейнер и выдаёт полноценные .ipa и .apk/.aab-файлы для магазинов приложений. Веб-код при этом остаётся ровно тем же — просто запускается внутри нативного WebView на устройстве.

Что такое Capacitor и как он работает

Capacitor — это инструмент от команды Ionic. Его задача проста: взять собранное веб-приложение (статические HTML, CSS, JS-файлы) и запустить его внутри нативного приложения.

На устройстве запускается системный WebView — на iOS это WKWebView, на Android — системный WebView. Внутри него крутится привычный JavaScript, как в браузере. Снаружи — нативная оболочка, которую пользователь скачивает из стора.

Главная деталь — мост (bridge). Это канал между JavaScript-кодом и нативными возможностями устройства. Через него веб-код может вызвать камеру, геолокацию, файловую систему, push-уведомления — то, чего не даёт обычный браузер.

В отличие от PWA, результат работы Capacitor — настоящий нативный бинарь, который проходит ревью магазина и устанавливается с иконкой на рабочий стол. Но веб-исходники при этом никуда не деваются: те же файлы продолжают работать и в браузере.

Как устроен проект

Capacitor подключается к существующему веб-проекту двумя пакетами:

npm install @capacitor/core
npm install -D @capacitor/cli
npx cap init

npx cap init просит имя приложения и appId — обратный домен вида ru.company.app. После этого создаётся файл конфигурации capacitor.config.ts:

import { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  appId: 'ru.company.app',
  appName: 'My App',
  webDir: 'dist',        // папка с собранным вебом
};

export default config;

webDir — главный параметр: именно из этой папки Capacitor берёт веб-сборку и переносит в нативные проекты.

Дальше добавляются платформы:

npm install @capacitor/ios @capacitor/android
npx cap add ios
npx cap add android

Команда add создаёт реальные нативные проекты в папках ios/ и android/ прямо в репозитории. Это важный момент: проекты под Xcode и Android Studio — это обычные файлы, которыми владеет разработчик. Их можно открывать, редактировать, добавлять нативные зависимости вручную.

Плагины: доступ к нативным возможностям

Сам мост — это просто канал. А конкретные нативные возможности предоставляют плагины.

Плагин — npm-пакет вида @capacitor/<что-то>. На JavaScript-стороне это обычные промис-функции. Под капотом плагин вызывает нативный код через мост.

Установка плагина:

npm install @capacitor/camera
npx cap sync

Использование в коде:

import { Camera, CameraResultType } from '@capacitor/camera';

async function takePhoto() {
  const photo = await Camera.getPhoto({
    quality: 90,
    resultType: CameraResultType.Uri,
  });
  return photo.webPath;
}

Никакого ручного моста писать не нужно — это работает из коробки.

Тот же код можно сделать платформо-зависимым: на устройстве идёт нативный вызов, в браузере — запасной вариант. Проверка среды выглядит так:

import { Capacitor } from '@capacitor/core';

if (Capacitor.isNativePlatform()) {
  // выполняется только на iOS и Android
  loadNativeModule();
}

Подробнее про набор нативных возможностей — в статье про нативные API.

Цикл разработки: сборка и sync

Рабочий процесс строится вокруг команды npx cap sync. После каждого изменения веб-кода:

npm run build       # собрать веб-проект
npx cap sync        # перенести сборку в нативные проекты

sync делает две вещи: копирует свежую веб-сборку из webDir в нативные проекты и обновляет нативные зависимости (доустанавливает плагины, правит конфиги платформ).

Порядок важен: сначала собрать веб, потом sync. Иначе в нативную обёртку попадёт старая версия.

После sync проект открывается в нативной среде для запуска на симуляторе или устройстве:

npx cap open ios      # откроет Xcode
npx cap open android  # откроет Android Studio

Именно из Xcode и Android Studio идёт подпись приложения, настройка профилей и выкладка в стор.

Чем Capacitor отличается от Cordova

Cordova — предшественник Capacitor, и решает ту же задачу. Но принцип хранения нативных проектов противоположный.

Cordova прячет нативные проекты в папке platforms/ и каждый раз генерирует их заново из конфигурации и хуков. Редактировать их руками бессмысленно — следующий build всё перезапишет.

Capacitor создаёт нативные проекты один раз и включает их в репозиторий. Разработчик владеет исходниками ios/ и android/ напрямую и может менять их в любой момент.

Ещё отличия:

  • мост в Capacitor быстрее и современнее;
  • плагины — обычные npm-пакеты с типами TypeScript, а не XML-конфигурации;
  • большинство старых Cordova-плагинов Capacitor умеет подхватывать — миграция не обязана быть полной переработкой.

Итог: меньше магии, больше контроля над нативной частью.

Коротко

  • Capacitor берёт собранное веб-приложение и оборачивает его в нативный контейнер с WebView.
  • На выходе — настоящие .ipa и .apk/.aab файлы, пригодные для магазинов приложений.
  • Конфигурация хранится в capacitor.config.ts; webDir указывает на папку с веб-сборкой.
  • Нативные проекты ios/ и android/ лежат в репозитории и принадлежат разработчику.
  • Нативные возможности — через плагины (@capacitor/camera, @capacitor/geolocation и др.).
  • Цикл работы: npm run buildnpx cap sync → открыть в Xcode/Android Studio.
  • В отличие от Cordova, нативные проекты не перегенерируются — их можно редактировать напрямую.

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

  • Нативные API через плагины — камера, геолокация, файловая система, права доступа.
  • WKWebView на iOS — как устроен WebView-контейнер на iOS.
  • Android TWA — альтернативный способ упаковки PWA без Capacitor.
  • Push-уведомления — как подключить FCM и APNs через Capacitor.