PWA & Tauri Mobile

이 문서가 답하는 질문: “데스크톱 + 모바일을 한 코드로 가려면 PWA와 Tauri 2.0 중 어느 쪽인가?” 한 줄 답 (Pyramid Top): “PWA는 설치 가능한 웹이고 Tauri 2.0은 작은 binary로 모바일까지 확장한다 — 둘 다 Electron보다 가볍지만, OS 깊은 통합에서 갈린다.”


Why — 왜 존재하는가

Electron은 데스크톱만 한다. 모바일이 함께 필요하면 — 다른 패키지(Capacitor·React Native·Flutter)를 별도 운영하거나, 웹 표준 기반으로 통합해야 한다.

옵션코드 1벌?설치 가능?OS 통합 깊이
Electron + CapacitorNo (별도 배포)Yes (각각)깊음
PWAYesYes (옵션)얕음
Tauri 1.xNo (데스크톱만)Yes깊음
Tauri 2.0YesYes깊음

How — 어떻게 동작하는가

PWA

  • manifest.json으로 설치 가능 선언.
  • Service Worker로 오프라인 캐시.
  • 브라우저가 호스트 — 설치돼도 브라우저 엔진 위.

Tauri 2.0 Mobile (2024 GA)

  • 같은 Rust 백엔드 + 웹 프론트.
  • iOS는 WKWebView, Android는 WebView (System WebView).
  • 빌드 결과: .app/.ipa (iOS), .apk/.aab (Android), .dmg/.exe/.AppImage (데스크톱).

What — 구체 사양·수치·예시

PWA Manifest

{
  "name": "My App",
  "short_name": "MyApp",
  "start_url": "/",
  "display": "standalone",
  "background_color": "#fff",
  "theme_color": "#2c3e50",
  "icons": [
    { "src": "/icons/192.png", "sizes": "192x192", "type": "image/png" },
    { "src": "/icons/512.png", "sizes": "512x512", "type": "image/png" }
  ]
}

Service Worker — 오프라인

// sw.js
self.addEventListener('install', (e) => {
  e.waitUntil(caches.open('v1').then(c => c.addAll([
    '/', '/style.css', '/app.js'
  ])));
});
 
self.addEventListener('fetch', (e) => {
  e.respondWith(
    caches.match(e.request).then(r => r || fetch(e.request))
  );
});

PWA의 OS API 한계 (iOS Safari 기준)

APIiOS PWAAndroid PWAElectronTauri
Notification✗ (16.4부터 부분)
File System Access✗ (부분)✓ (Node fs)✓ (rust)
Camera
Background Sync
Push (FCM/APNs)16.4+✓ (커스텀)
시스템 트레이
키보드 단축키 (전역)
자동 시작 (부팅)

Tauri 2.0 Mobile 빌드

# Android
cargo tauri android init
cargo tauri android dev
cargo tauri android build
 
# iOS
cargo tauri ios init
cargo tauri ios dev
cargo tauri ios build

Tauri 2.0 권한 시스템 (mobile-first 설계)

# tauri.conf.json
{
  "tauri": {
    "allowlist": {
      "all": false,
      "fs": {
        "readFile": true,
        "writeFile": true,
        "scope": ["$APPDATA/*", "$DOWNLOAD/*"]
      },
      "shell": { "execute": false },
      "dialog": { "open": true }
    }
  }
}

디폴트 deny + 명시적 allow. Electron이 디폴트 allow + 명시적 deny인 것과 반대.


What-if — 잘못 쓰면

  • 함정 1: PWA로 가능하다고 시스템 트레이·전역 단축키를 요구 → 불가능. 사용자가 ★1점 리뷰.
  • 함정 2: Tauri 2.0 모바일에서 Electron 패턴 그대로 적용 → BrowserWindow가 없고, IPC도 다르다. 마이그레이션이 재작성에 가까움.
  • 함정 3: iOS PWA의 Storage 7일 정책 → 사용자가 1주일 안 쓰면 IndexedDB 삭제. 오프라인 앱은 PWA 부적합.
  • 함정 4: PWA를 App Store에 못 올림 → 사용자 발견 채널이 공유 URL뿐.

Insight — 흥미로운 이야기

“Twitter Web App이 PWA 시대의 선도자였다가 후퇴했다”

2017년 Twitter Lite는 PWA로 모바일 웹 경험을 네이티브 수준으로 끌어올린 사례로 유명했다 — 200KB shell + Service Worker로 첫 화면 1초 미만. 그 결과 일부 시장에서 네이티브 앱을 대체하기까지 했다.

그러나 — Twitter는 결국 네이티브 앱으로 회귀했다. 이유는 PWA의 플랫폼 신뢰 문제: 푸시 알림 제약, App Store 부재, OAuth 흐름의 어색함. 같은 시기 Starbucks PWA는 유지되며 거꾸로 성공 사례가 되었다 — 카탈로그 조회 같은 얕은 통합만 필요한 도메인이었기 때문.

교훈 — PWA는 제품 깊이에 매우 민감하다. 얕은 통합 + 광범위한 디바이스면 PWA가 압승, 깊은 OS 통합이 필요하면 네이티브(Electron·Tauri·React Native)가 답. Tauri 2.0 모바일이 그 사이를 노리는 베팅이고, 2024~2025년이 그 베팅의 분기점이다.


요약

  • PWA = 얕은 통합이 충분한 도메인의 답.
  • Tauri 2.0 = 깊은 통합작은 binary로 달성하는 새 답.
  • iOS PWA는 여전히 제약이 많다 — 푸시·스토리지·자동 시작 등.
  • 결정 기준: OS API 깊이 × 제품 코어 가치.