forked / Architecture

ADR-039: PWA Only, No Native Shell

Status: Accepted Date: 2026-10-18

Context

A native shell (Capacitor for iOS and Android) around the React PWA would add native projects, SDKs, signing, store releases, and a second runtime path (native keyboard and deep-link handling) to a product whose value is a private, offline-first web app that anyone can self-host.

Decision

forked ships as a PWA only:

  1. The one React and Vite frontend is the only client. There is no Capacitor project, no ios/ or android/ folder, and no native plugin.
  2. Mobile reach comes from the installable PWA (service worker, manifest, offline storage) and mobile-first UI.
  3. Invite links, pairing codes, and the QR scanner use browser capabilities only (BarcodeDetector with a jsqr fallback).
  4. Every deployment has a serving origin, so /forked-config.json can always announce the sync mode (ADR-038).

Consequences

  • One runtime path, no store reviews, no signing, no host SDKs; updates roll out through the service worker.
  • The iOS keyboard accessory bar cannot be hidden, and platform APIs that browsers lack are out of reach.
  • A link opened from the system camera on iPhone lands in Safari with storage separate from the installed PWA, so the pairing code stays the in-app join path.
  • WebKit coverage stays in CI, because Safari and installed iOS PWAs run on it.

View source on GitHub