Compatibility baseline
A mini app runs in JavaScriptCore on iOS and V8 on Android. That is not a design choice Sollar made; it is a legal one it inherited.
Apple’s Guideline 2.5.6 requires that apps browsing the web “use the appropriate WebKit framework and WebKit JavaScript.” The Embedded Browser Engine Entitlement that would allow otherwise exists only in the European Union, and qualifying for it requires 90% pass rates on the Web Platform Tests, 80% on Test262, a memory-safe implementation language and a 30-day CVE remediation commitment.
So the engines differ, and they will keep differing. What Sollar can do is name a floor and test against it.
The floor
Section titled “The floor”| Baseline | |
|---|---|
| JavaScript | ECMAScript 2022 |
| CSS | Everything in Baseline “Widely available” as of 2024 |
| iOS | WKWebView on iOS 16.4+ |
| Android | Android System WebView 114+ |
Anything at or below this floor works on every device Sollar supports. Anything above needs feature detection.
What ES2022 gives you
Section titled “What ES2022 gives you”Class fields and private methods, at(), Object.hasOwn(), top-level await, Error.cause,
Array.prototype.findLast(), RegExp match indices. Modules, async/await, optional chaining and
nullish coalescing are all far below the floor.
Above the floor — check first
Section titled “Above the floor — check first”| Feature | Note |
|---|---|
Array.prototype.group / groupBy | Shipped at different times on the two engines. Detect. |
Temporal | Not on the floor. Use a library. |
| Decorators | Compile them; do not ship them raw. |
structuredClone | Available, but with divergent handling of some types. |
| Web Locks | Not on iOS. |
showOpenFilePicker | Chromium only. Fall back to <input type="file">. |
container-queries | Above the floor on the oldest supported iOS. Detect. |
:has() | Same. |
if ('group' in Array.prototype) { /* … */ } else { /* … */ }if (CSS.supports('selector(:has(a))')) { /* … */ }Feature detection, never user-agent sniffing. The user agent inside a mini app is deliberately uninformative, and treating it as a capability signal will produce wrong answers on both platforms.
Known divergences
Section titled “Known divergences”| JavaScriptCore (iOS) | V8 (Android) | |
|---|---|---|
| Stack trace format | Error.stack differs in shape | |
toLocaleString output | ICU version differs; the string differs | |
| Regex Unicode property escapes | Both support them; edge cases differ | |
| Timer clamping in background | More aggressive on iOS | |
| Number formatting near precision limits | Differs in the last digit |
The practical rule: never parse a formatted string you produced with toLocaleString. Format
for display, compute on the underlying value. This is the single most common source of a bug that
appears on one platform only.
Conformance suite
Section titled “Conformance suite”sollar test --conformanceRuns Sollar’s own suite against whichever runtime is attached — dev server, iOS simulator, Android
emulator, or a physical device. It covers the ES2022 floor, the CSS baseline, every sollar.*
method, and the permission paths.
The permission tests run identically in all three environments. Development, trial and production share one authorisation code path; what changes between environments is data and endpoints, never the permission check. Environment-divergent permission behaviour is one of the six vulnerability categories this platform is designed against — see Security model.
Version policy
Section titled “Version policy”- The floor rises at most once a year, announced at least two release cycles ahead.
- A raised floor never breaks an installed mini app; it changes what new submissions may assume.
- Removing anything from the bridge requires a major version and a deprecation window.
Secure context
Section titled “Secure context”Mini apps run at a synthetic origin over https, so they are secure contexts and crypto.subtle,
service workers and the rest are available.