Integrate an SDK

Feature matrix

October 2026: Android, iOS and web SDK 0.3, Flutter package 0.4. Use it to decide which hooks a platform needs before you promise a bug will replay.

tested implemented and covered by automated tests or the recorded end-to-end run · implemented implemented, not tested here · partial works with a documented limitation · no not implemented or planned.

i

The Android, iOS and web end-to-end runs were recorded on 2026-10-21 (Pixel 6 API 35 emulator, iPhone 18 Pro simulator on iOS 27, Chromium 153). Flutter E2E figures come from the earlier measurement in the Flutter README; its unit suites were re-run, its device E2E was not.

Capture

FeatureFlutterAndroidiOSWeb
Bounded flight recorder (20k events / 5 min, launch + periodic checkpoints)testedtestedtestedtested
Manual capture (capture)testedtestedtestedtested
Automatic capture: uncaught errorstested (FlutterError.onError, PlatformDispatcher.onError)tested (JVM uncaught, chained handler)partial (NSException via chained handler; Swift traps/signals not captured)tested (error, unhandledrejection)
Crash capsule persisted, uploaded next launchn/a (Dart errors do not end the process)testedtestedn/a (errors do not end the page)
Assertions check / fail, reportErrortestedtestedtestedtested
Pointer capturetestedtested (Window.Callback, dp)tested (explicit BugCapsuleWindow / recordTouches)tested (Pointer Events, target descriptor)
Semantic actionstestedtested (Views + Compose)tested (UIKit + SwiftUI)tested (core + React)
Tracked text, sensitive fieldstestedtested (password input types forced)tested (isSecureTextEntry forced)tested (password inputs, data-bugcapsule-sensitive)
Key events—tested (Back, key event)—— (tracked inputs only)
Navigationtested (GoRouter)tested (Jetpack Navigation)tested (UINavigationController proxy, explicit, SwiftUI)tested (History API; React Router listener)
Lifecycletestedtestedtestedtested (visibility, pagehide/pageshow)
Statetested (BLoC, Riverpod, Provider, GetX, MobX)tested (registered serializers, ViewModels)tested (registered state objects)tested (registered serializers, React hook)
Storage checkpoints (allowlisted)tested (SharedPreferences)tested (SharedPreferences, Preferences DataStore)tested (UserDefaults)tested (localStorage, sessionStorage); implemented (IndexedDB adapters: unit-level only)
HTTP capturetested (Dio, package:http)tested (OkHttp; Retrofit through it)tested (URLSession via URLProtocol); implemented (Alamofire through an instrumented configuration, documented, not tested)tested (fetch, XMLHttpRequest)
Bounded body capture, streams untouchedtestedtestedtestedtested (clone() read up to the limit)
In-flight requests at capture (http.pending)—testedtested—
Redaction before persistence (shared conformance fixtures)testedtestedtestedtested
Remote config, kill switch, samplingtestedtestedtestedtested
Rejected ingest keystops capture, purges queuestops capture, keeps queuestops capturestops capture, purges queue
Offline outbox (10 / 10 MiB / 7 days, backoff, Retry-After)testedtestedtestedtested (IndexedDB, cross-tab safe)
Runtime + capability metadata in capsulestestedtestedtestedtested

Replay

FeatureFlutterAndroidiOSWeb
Runs the real app codetestedtested (instrumentation, in-process engine)tested (XCUITest launches the app, in-app engine)tested (Playwright, in-page engine)
Pointer replaytestedtested (sendPointerSync)— (input.pointer.replay: unsupported, material pointer.unsupported)tested (trusted Playwright input; mismatch/ambiguity reported)
Semantic action replaytestedtestedtestedtested
Tracked text replaytestedtestedtestedtested
Lifecycle replaytestedtested (ActivityScenario states)partial (posted notifications)partial (synthetic visibility events)
Checkpoint restoration before app codetestedtested (runner onCreate, before Application.onCreate)tested (in BugCapsule.start())tested (init script + init())
Late / failed restoration reportedtestedtestedtestedtested
Deterministic network replay (key + occurrence, latency, errors, cancel)testedtestedtestedtested (fetch + XHR)
Strict network (unrecorded never reaches real services)testedtestedtestedtested (+ runner blocks escaped requests)
Idle compressiontestedtestedtestedtested
Clock / random hooks (explicit only)testedtestedtestedtested
Production replay protectiontested (release builds)tested (androidTest runner + debuggable)tested (#if DEBUG + launch argument)tested (allowReplay + runner bindings)
Attempt isolationrelaunchpm clearuninstallfresh browser context
Physical devicespartial (iOS needs --lan)implemented (adb device path, not tested)— (simulator only; signing/devicectl planned)n/a
Browsersn/an/an/atested Chromium; implemented capture in Firefox/Safari (untested); no replay elsewhere
Cross-runtime replay———— (CLI reports INCOMPATIBLE)

CLI and project

FeatureFlutterAndroidiOSWeb
inspect / run / verify / regress add / regress runtestedtestedtestedtested
Source-revision replay (git worktree pin)testedimplemented (generic; E2E used a scratch git copy)implemented (generic; not exercised)tested (scratch git copy: pinned REPRODUCED, working tree FIXED)
Prebuilt artifacts—implemented (--apk, --test-apk)implemented (--xctestrun)tested (--app-url)
Per-attempt token, attemptId, stale-report rejection, Origin refusaltestedtestedtestedtested
Timeouts, Ctrl-C cleanuptestedtestedtestedtested
Upload, run results, triage, sharingtestedtestedtestedtested (CORS)
Filter capsules by platformtestedtestedtestedtested

Recorded end-to-end results (this session)

StepAndroid (Pixel_6_2, API 35)iOS (iPhone 18 Pro sim, iOS 27)Web (Chromium 153)
Capture + uploadrace crash, null price, legacy cart, couponcoupon assertion, race NSException, legacy cartrace, legacy cart, discontinued item, coupon
runREPRODUCED 3/3 (independent re-run 2/2)REPRODUCED 3/3REPRODUCED 3/3
verify without fixSTILL FAILING 3/3STILL FAILING 3/3STILL FAILING 3/3
verify with isolated fixFIXED 3/3 (independent re-run 2/2)FIXED 3/3FIXED 3/3
Restoration control (checkpoint removed)—NOT REPRODUCED 0/1NOT REPRODUCED 0/2
regress runfail without fix, pass with fixfail without fix, pass with fixfail without fix, pass with fix
Offline capture → restart → uploadtested (airplane mode)tested (BugCapsule unreachable)tested (blocked uploads, reload)

Shared verdict behaviour in all runtimes: a fix that makes the app send requests the recording never saw yields INCONCLUSIVE, never FIXED (strict network). This was observed for the web discontinued-item fix and the Android null-price and legacy-cache fixes.

Which hooks each platform needs most

PlatformDon't skip
FlutterSerializers for BLoC/Riverpod state you want restored from periodic checkpoints; clock.now().
AndroidOkHttp interceptor last; storage allowlists; sensitive = true for Compose password fields.
iOSSemantic actions for every important tap (no pointer replay); BugCapsuleURLSession in integrations; check before code that traps.
Webmode: 'qa' in QA builds; data-bugcapsule-action on clickable elements; your origin allowed by your BugCapsule team; allowReplay only in test builds.