BrowserEngineKit
Framework for building web browsers with alternative (non-WebKit) rendering
engines on iOS and iPadOS. Provides process isolation, XPC communication,
capability management, and system integration for browser apps that implement
their own HTML/CSS/JavaScript engine. Examples target Swift 6.3 and current
Apple SDKs.
BrowserEngineKit is a specialized framework. Alternative browser engines are
available only through Apple-approved entitlement profiles and supported-region
device eligibility. EU support applies to eligible users on iOS 17.4+ and
iPadOS 18+; Japan support starts with iOS 26.2 and adds explicit PAC/MIE
security requirements for browser apps. Development and testing can occur
anywhere. The companion frameworks BrowserEngineCore (low-level primitives) and
BrowserKit (eligibility checks, data transfer) support the overall workflow.
Contents
Workflow
- Verify regional eligibility, default-browser requirements, device capability, and approved entitlements before implementation.
- Model the host plus web-content, networking, and rendering extensions and follow the required bootstrap order.
- Create, retain, invalidate, and reconnect extension processes/XPC channels as explicit lifecycle states.
- Request only the capabilities each extension needs and keep JIT, sandbox, media, layer, text, and download responsibilities separated.
- Verify eligible/ineligible devices, process crashes, relaunch, backgrounding, downloads, memory pressure, and security boundaries.
Route by Task
- Read core implementation details for eligibility, entitlements, architecture, process management, capabilities, sandboxing, JIT, and downloads.
- Read extended BrowserEngineKit patterns for text interaction, layer hosting, scroll coordination, bookmarks, content filtering, and XPC recipes.
Core Decisions
- Treat entitlement approval and runtime eligibility as separate gates.
- Launch extensions only from the host and discard process objects after invalidation.
- Apply JIT-related entitlements only to the intended content process.
- Never weaken sandbox boundaries to simplify cross-process communication.
Common Mistakes
DON'T: Skip the bootstrap sequence
// WRONG - content extension has no path to other extensions
let contentProcess = try await WebContentProcess(
bundleIdentifier: nil, onInterruption: {}
)
// Immediately start sending work without connecting to networking/rendering
// CORRECT - broker connections through the host app
let networkEndpoint = try await networkProxy.getEndpoint()
let renderEndpoint = try await renderProxy.getEndpoint()
try await contentProxy.bootstrap(
renderingExtension: renderEndpoint,
networkExtension: networkEndpoint
)
DON'T: Launch extensions from other extensions
// WRONG - extensions cannot launch other extensions
// (inside a WebContentExtension)
let network = try await NetworkingProcess(...)
// CORRECT - only the host app launches extensions
// Host app creates all processes, then brokers connections
DON'T: Use extension process objects after invalidation
// WRONG
contentProcess.invalidate()
let conn = try contentProcess.makeLibXPCConnection() // Error
// CORRECT - create a new process if needed
let newProcess = try await WebContentProcess(
bundleIdentifier: nil, onInterruption: {}
)
DON'T: Apply JIT entitlements to non-content extensions
JIT compilation entitlements (com.apple.security.cs.allow-jit) are valid
only on web content extensions. Adding them to the host app, rendering
extension, or networking extension causes App Store rejection.
DON'T: Hard-code region eligibility
// WRONG
if Locale.current.region?.identifier == "DE" {
useAlternativeEngine()
}
// CORRECT - use the system eligibility API
let eligible = try await BEAvailability.isEligible(for: .webBrowser)
if eligible {
useAlternativeEngine()
}
DON'T: Forget to set UIRequiredDeviceCapabilities
Without web-browser-engine in UIRequiredDeviceCapabilities, users on
unsupported devices can download the app and hit runtime failures.
Review Checklist
References
1---2name: browserenginekit3description: Build alternative browser engines using BrowserEngineKit. Use when developing a non-WebKit browser engine for iOS/iPadOS in supported regions, managing web content/rendering/networking extension processes, configuring GPU and networking process capabilities, checking alternative-engine device eligibility, or reviewing BrowserEngineKit entitlements and Info.plist setup.4---56# BrowserEngineKit78Framework for building web browsers with alternative (non-WebKit) rendering9engines on iOS and iPadOS. Provides process isolation, XPC communication,10capability management, and system integration for browser apps that implement11their own HTML/CSS/JavaScript engine. Examples target Swift 6.3 and current12Apple SDKs.1314BrowserEngineKit is a specialized framework. Alternative browser engines are15available only through Apple-approved entitlement profiles and supported-region16device eligibility. EU support applies to eligible users on iOS 17.4+ and17iPadOS 18+; Japan support starts with iOS 26.2 and adds explicit PAC/MIE18security requirements for browser apps. Development and testing can occur19anywhere. The companion frameworks BrowserEngineCore (low-level primitives) and20BrowserKit (eligibility checks, data transfer) support the overall workflow.2122## Contents2324- [Workflow](#workflow)25- [Route by Task](#route-by-task)26- [Core Decisions](#core-decisions)27- [Common Mistakes](#common-mistakes)28- [Review Checklist](#review-checklist)29- [References](#references)3031## Workflow32331. Verify regional eligibility, default-browser requirements, device capability, and approved entitlements before implementation.342. Model the host plus web-content, networking, and rendering extensions and follow the required bootstrap order.353. Create, retain, invalidate, and reconnect extension processes/XPC channels as explicit lifecycle states.364. Request only the capabilities each extension needs and keep JIT, sandbox, media, layer, text, and download responsibilities separated.375. Verify eligible/ineligible devices, process crashes, relaunch, backgrounding, downloads, memory pressure, and security boundaries.3839## Route by Task4041- Read [core implementation details](references/core-implementation.md) for eligibility, entitlements, architecture, process management, capabilities, sandboxing, JIT, and downloads.42- Read [extended BrowserEngineKit patterns](references/browserenginekit-patterns.md) for text interaction, layer hosting, scroll coordination, bookmarks, content filtering, and XPC recipes.4344## Core Decisions4546- Treat entitlement approval and runtime eligibility as separate gates.47- Launch extensions only from the host and discard process objects after invalidation.48- Apply JIT-related entitlements only to the intended content process.49- Never weaken sandbox boundaries to simplify cross-process communication.5051## Common Mistakes5253### DON'T: Skip the bootstrap sequence5455```swift56// WRONG - content extension has no path to other extensions57let contentProcess = try await WebContentProcess(58 bundleIdentifier: nil, onInterruption: {}59)60// Immediately start sending work without connecting to networking/rendering6162// CORRECT - broker connections through the host app63let networkEndpoint = try await networkProxy.getEndpoint()64let renderEndpoint = try await renderProxy.getEndpoint()65try await contentProxy.bootstrap(66 renderingExtension: renderEndpoint,67 networkExtension: networkEndpoint68)69```7071### DON'T: Launch extensions from other extensions7273```swift74// WRONG - extensions cannot launch other extensions75// (inside a WebContentExtension)76let network = try await NetworkingProcess(...)7778// CORRECT - only the host app launches extensions79// Host app creates all processes, then brokers connections80```8182### DON'T: Use extension process objects after invalidation8384```swift85// WRONG86contentProcess.invalidate()87let conn = try contentProcess.makeLibXPCConnection() // Error8889// CORRECT - create a new process if needed90let newProcess = try await WebContentProcess(91 bundleIdentifier: nil, onInterruption: {}92)93```9495### DON'T: Apply JIT entitlements to non-content extensions9697JIT compilation entitlements (`com.apple.security.cs.allow-jit`) are valid98only on web content extensions. Adding them to the host app, rendering99extension, or networking extension causes App Store rejection.100101### DON'T: Hard-code region eligibility102103```swift104// WRONG105if Locale.current.region?.identifier == "DE" {106 useAlternativeEngine()107}108109// CORRECT - use the system eligibility API110let eligible = try await BEAvailability.isEligible(for: .webBrowser)111if eligible {112 useAlternativeEngine()113}114```115116### DON'T: Forget to set UIRequiredDeviceCapabilities117118Without `web-browser-engine` in `UIRequiredDeviceCapabilities`, users on119unsupported devices can download the app and hit runtime failures.120121## Review Checklist122123- [ ] `com.apple.developer.web-browser-engine.host` entitlement on host app124- [ ] Each extension has its type-specific entitlement125- [ ] `UIRequiredDeviceCapabilities` includes `web-browser-engine`126- [ ] `arm64e` instruction set configured for all iOS device targets127- [ ] `arm64e` is not set for Simulator targets128- [ ] Swift packages built with `iOSPackagesShouldBuildARM64e` workspace setting129- [ ] Extension point identifiers set correctly in each extension's Info.plist130- [ ] Interruption handlers implemented for all process types131- [ ] Bootstrap sequence connects content extension to networking and rendering132- [ ] Capabilities granted before work begins and invalidated when done133- [ ] Visibility propagation interaction added to browser content views134- [ ] Restricted sandbox applied to content extensions after initialization135- [ ] `BEAvailability` used for eligibility checks instead of manual region logic136- [ ] Memory attribution entitlements use the host app bundle ID as their value137- [ ] Download progress reported via `BEDownloadMonitor` for active downloads on iOS 18.2+138- [ ] Memory tagging enabled for Japan distribution on iOS 26.2+ (recommended for EU)139140## References141- Extended patterns (text interaction, layer hosting, scroll views, file bookmarks, XPC communication, content filtering): [references/browserenginekit-patterns.md](references/browserenginekit-patterns.md)142- [BrowserEngineKit framework](https://sosumi.ai/documentation/browserenginekit)143- [Designing your browser architecture](https://sosumi.ai/documentation/browserenginekit/designing-your-browser-architecture)144- [Creating browser extensions in Xcode](https://sosumi.ai/documentation/browserenginekit/creating-browser-extensions-in-xcode)145- [Managing the browser extension life cycle](https://sosumi.ai/documentation/browserenginekit/managing-the-browser-extension-lifecycle)146- [Using XPC to communicate with browser extensions](https://sosumi.ai/documentation/browserenginekit/using-xpc-to-communicate-with-browser-extensions)147- [Web Browser Engine Entitlement](https://sosumi.ai/documentation/bundleresources/entitlements/com.apple.developer.web-browser-engine.host)148- [BrowserKit framework](https://sosumi.ai/documentation/browserkit)149- [BrowserEngineCore framework](https://sosumi.ai/documentation/browserenginecore)150- [Sample: Developing a browser app with an alternative engine](https://sosumi.ai/documentation/browserenginekit/developing-a-browser-app-that-uses-an-alternative-browser-engine)151- [Core implementation details](references/core-implementation.md) -- setup, API wiring, and focused implementation recipes moved out of the entrypoint.