Представьте: у вас уже есть веб-приложение на 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 build→npx cap sync→ открыть в Xcode/Android Studio. - В отличие от Cordova, нативные проекты не перегенерируются — их можно редактировать напрямую.
Что почитать дальше
- Нативные API через плагины — камера, геолокация, файловая система, права доступа.
- WKWebView на iOS — как устроен WebView-контейнер на iOS.
- Android TWA — альтернативный способ упаковки PWA без Capacitor.
- Push-уведомления — как подключить FCM и APNs через Capacitor.