The judgement in two sentences
After the memory was measured, the evaluation's comparison table ended with two sentences that are worth learning by heart: "Chromium is still the better engine for raw compatibility and extensions. WebKit is far the better engine to build a browser of our own on." Both halves are true at once. This lesson is about holding them together: what WebKit hands a browser of its own through public API, and what it does not have at all.
What public API gives a browser of its own
The evaluation lists it item by item, each with its grade. The ones that shaped Voyager:
- One isolated store per identity.
WKWebsiteDataStore(forIdentifier:), available since macOS 14 and iOS 17, gives a persistent store named by an id you choose. Several can be live at once, and a pop-up inherits its opener's store. In Chromium a tab with its own logins needs its own request context, which is a whole profile, so its extensions and history split off too; keeping only the logins apart while tabs share the rest took Brave a patch set. Here it is one initializer, and nothing else splits. The gate later confirmed it: a cookie and a stored value set in one identity were invisible in the other. - A permission decision per request, with the origin. A page asking for the microphone or camera reaches the host with the requesting origin before any prompt, so the host can decide per site.
- Secure contexts, and their one hard edge. Capture needs a secure context, and WebKit has no public way to mark a plain-http origin secure. Family apps are therefore opened at HTTPS names, or at loopback on the Mac that serves them.
- Sleep and restore.
interactionStatecarries a page's history, scroll position and form data into a new web view. - Page reading. Script in an isolated content world, snapshots, PDF and web archives. There is no public Reader or text-extraction call, so a reader for Pippa has to be written.
- Content blocking by compiled rule lists, 150,000 rules per list. (The API exists; Voyager has not built ad or tracker blocking yet.)
- The system's codecs and the system's patches. H.264, HEVC and AAC come with the OS, and security fixes arrive with macOS and iOS updates. The app ships no engine.
- One Swift codebase for three devices. iOS allows only WebKit outside the EU and Japan, and even there another engine needs a separate entitlement from Apple, so the same engine on the Mac means the same child code on iPhone and iPad.
Extensions are the newest piece. Apple's extension-hosting API for web-view apps (WKWebExtension, WKWebExtensionContext, WKWebExtensionController) is public since macOS 15.4 and iOS 18.4. That is why Voyager's package sets its platform floors at exactly those releases: platforms: [.macOS("15.4"), .iOS("18.4")]. It loads an unpacked Manifest V3 folder as it is, within the APIs WebKit implements, and leaves the tab model, the action pop-up, permission prompts and native messaging to the host. The precedent that made this believable is Orion, a WebKit browser that runs Chrome and Firefox extensions: about 70 percent of the WebExtensions API, version 1.0 in November 2025 after six years of its own work (graded Secondary).
What WebKit lacks, by name
- Touch ID passkeys. Measured on 2026-10-04 in a build without Apple's web-browser entitlement:
PublicKeyCredentialexists, butisUserVerifyingPlatformAuthenticatorAvailable()answers false, so a page gets no platform authenticator. - Device APIs. WebUSB, Web Serial, Web Bluetooth and WebHID, which WebKit declines, and Web MIDI, which is absent.
- Chrome's own surroundings. Google Docs offline (Chrome and Edge only), the Chrome Web Store as an install path, Chrome DevTools (Web Inspector instead), and extensions that drive Chrome's tabs through Chrome-only APIs, as the AI assistant extensions do.
- A tab mute. The public header has calls to pause and suspend media, and no mute; Safari's mute is private. Voyager's tab speaker mutes the page's media elements from its own content world in every frame, so sound made without an element (an
Audioobject never attached, WebAudio) is neither heard nor muted by it. - A find count.
find(_:configuration:)answers only whether there was a match. "3 of 17" is counted from the page's own visible text. - On iPhone and iPad: service workers in ordinary tabs, Add to Home Screen, default-browser status and passkeys on any site all need the same managed entitlement.
That entitlement was a real decision, and Dad made it on 2026-10-26 after hearing that Apple grants it only with a public TestFlight link and external Beta App Review:
아니, 근데 이거 다 디폴트 브라우져 자격 얻는데 필요한 깐깐한 심사 아니야? 디폴트로 안 쓰면 그만이잖아? 이걸 외부 베타 테스트 심사까지 받는다고? 그건 하면 안 돼.
"Wait, isn't all of this the strict review for default-browser status? If I don't use it as the default, that's the end of it. External beta review, for this? We shouldn't do that." So Voyager carries no web-browser entitlement on any device. The cost is written down as current fact: no Touch ID passkey on a page, so cwkPippa's passkey sign-in shows no button and the family PIN signs in instead.
The family's own web apps, searched
One more check went into the ruling. The family runs many web apps of its own, and a WebKit browser that broke them would fail its first job. So every family frontend was searched for Chromium-only web APIs. Two uses turned up. Bonfire, the music app, asks for Web MIDI and already treats its absence as "no MIDI", so on WebKit its MIDI input simply does not work. Loomis prefers the folder picker and already carries a fallback for Safari. Nothing else in the search reached for Chromium, and the family's web apps were already running on iPhone and iPad, which are WebKit.
Bonfire's MIDI is the one family-side gap, and it stays an open ruling: a native CoreMIDI bridge for that page, or Bonfire's MIDI stays in another browser. The full table of engine-bound gaps, and why naming them keeps "superset" honest, is in the first track's lesson on named gaps.