See what needs attention.
Group crashes, errors, ANRs and app hangs into issues. Track crash-free sessions, release adoption, traces and web or mobile vitals. Route alerts to email, Slack or webhooks.
Explore monitoringApplication monitoring · Replay · Verification
Monitor crashes, releases and performance. Reproduce supported failures against your real code, check the fix, and keep the scenario in CI. One platform for developers and QA.
Explore the demo without signup or SDK installation.
Now in beta. Create a workspace with Google or GitHub. Get beta support ·
Capsule illustration · sample failure
The problem
QA sees a bug. The developer gets a screen recording and a description, then spends the afternoon guessing. The bugs that resist are the ones that depend on what the server returned, how long it took, or state left on the device from an earlier version.
A capsule carries exactly that context, so the failure comes back on the developer's simulator instead of in a meeting.
Works on my machine ≠ fixed
The BugCapsule platform
Bring production signals, reproducible context, repair evidence and recovery controls into the same workflow.
Group crashes, errors, ANRs and app hangs into issues. Track crash-free sessions, release adoption, traces and web or mobile vitals. Route alerts to email, Slack or webhooks.
Explore monitoringConnect stack traces, breadcrumbs, user feedback and linked capsules. Assign issues, discuss findings and follow the work through GitHub or Jira.
See the capsule workspaceReplay recorded actions, responses and state against your app. Inspect verification results and add supported scenarios to your regression suite.
Follow the workflowSwitch a broken feature off in apps already on your users' phones, enforce it on your server too, then restore it in stages with approvals and an audit trail.
Explore Emergency RecoveryFlutter, Android, iOS and web. Replay coverage depends on the runtime, instrumentation and recorded dependencies. Emergency Recovery needs the next Flutter, Android and iOS SDK releases. Signed patches for logic and layouts your app has already registered are in early access.
How it works
One capsule, from the failing build to your CI.
When your app fails, the SDK saves a capsule: the actions, HTTP responses with their timing, state and storage that led there. It is redacted on the device before upload.
Actions + network + stateThe CLI checks out the exact commit and re-runs your real app on a simulator, an emulator or Chromium, feeding it the recorded inputs until the failure fires again.
bugcapsule run <id> -n 3
Replay against your working tree and inspect each attempt’s verdict and evidence. Keep the recorded scenario as a regression test in your CI. Results apply to that scenario and its supported dependencies.
bugcapsule verify <id> -n 5
Dashboard · design preview
Inspect the timeline, state, events and network of a capsule, copy the replay and verify commands, and share it with your team.
Capsule e73f5ad0
Event 284 / 612
› onTap()
lib/screens/cart.dart:87
⌄ CartState (expanded)
{
"items": [ … ],
"price": null,
"subtotal": 84.0
}
Actions
For developers and QA
Connect what the app should do with what actually happened. Keep the brief, the bug and the repair attempt linked.
Set up your workspaceImport a Markdown brief, review structured context and test scenarios, and publish an approved version. Repair tasks pin that version so everyone works from the same expectations.
Prepare a repair task from an issue or capsule. Connect Codex, Claude Code or another MCP client with scoped access, then review the task timeline, agent-reported results and checks.
QA and agent features require an enabled workspace and access permissions. Your agent runs in your own tools; preparing a task does not automatically start a repair.
Platforms
One capsule format, one bugcapsule CLI and one dashboard for all four. A capsule replays on the runtime that captured it.
Replays on iOS simulators and Android emulators
package:http (Retrofit, Chopper)REPRODUCED 3/3 FIXED 2/2
Replays on an emulator through instrumentation
REPRODUCED 3/3 FIXED 3/3
Replays on a simulator through XCUITest
REPRODUCED 3/3 FIXED 3/3
Replays in Chromium through Playwright
fetch and XMLHttpRequestREPRODUCED 3/3 FIXED 3/3
Results from each SDK's demo shop app against a local backend: Flutter on an iPhone 18 Pro simulator (iOS 27), Android on a Pixel 6 emulator (API 35), iOS on an iPhone 18 Pro simulator (iOS 27), web in Chromium 153.
Integrate
Add the SDK for your platform, start it first thing, attach your HTTP client and router, and pin the commit at build time.
# pubspec.yaml: one package, every integration
dependencies:
bug_capsule: 0.4.1-beta.7
// main.dart
import 'package:bug_capsule/bug_capsule.dart';
final bugCapsuleDio = BugCapsuleDio(rules: [
// Fields that differ on every run must not affect request matching.
EndpointRule('POST', '/api/checkout', ignoreBodyFields: {'timestamp', 'nonce'}),
]);
final bugCapsuleRouter = BugCapsuleGoRouter();
void main() => BugCapsule.init( // first line of main
config: const BugCapsuleConfig(
appVersion: '1.4.0',
appBuild: '52',
mode: CaptureMode.qa,
backend: BugCapsuleBackendConfig(url: 'https://bugcapsule.example.com', ingestKey: 'bci_...'),
),
integrations: [
BugCapsuleBloc(states: [ // or BugCapsuleRiverpod, BugCapsuleNotifiers, BugCapsuleGetx, BugCapsuleMobx
BugCapsuleState<CartBloc, CartState>(toJson: (s) => s.toJson(), fromJson: CartState.fromJson),
]),
bugCapsuleDio, // or BugCapsuleHttp for package:http and Chopper
bugCapsuleRouter,
BugCapsuleSharedPreferences(),
],
appRunner: () => runApp(const MyApp()),
);
// where you build Dio and GoRouter:
bugCapsuleDio.attach(dio);
final router = GoRouter(initialLocation: bugCapsuleRouter.initialLocation('/'), routes: [...]);
bugCapsuleRouter.attach(router);
// QA capture button:
MaterialApp.router(builder: (context, child) => BugCapsuleOverlay(child: child!), ...);
# Build with the commit pinned so replay can check out the same code
flutter build ipa --dart-define=BUGCAPSULE_GIT_SHA=$(git rev-parse HEAD) --dart-define=BUGCAPSULE_MODE=qa
// app/build.gradle.kts
android {
defaultConfig {
testInstrumentationRunner = "dev.bugcapsule.android.replay.BugCapsuleReplayRunner"
// The CLI passes -PbugcapsuleGitSha=<sha> so capsules carry the build's commit.
buildConfigField("String", "BUGCAPSULE_GIT_SHA", "\"${providers.gradleProperty("bugcapsuleGitSha").getOrElse("")}\"")
buildConfigField("String", "BUGCAPSULE_INGEST_KEY", "\"${providers.environmentVariable("BUGCAPSULE_INGEST_KEY").getOrElse("")}\"")
}
buildFeatures.buildConfig = true
}
dependencies {
implementation("io.github.bugcapsule:bugcapsule-android:0.4.1-beta.5")
implementation("io.github.bugcapsule:bugcapsule-okhttp:0.4.1-beta.5")
implementation("io.github.bugcapsule:bugcapsule-navigation:0.4.1-beta.5")
implementation("io.github.bugcapsule:bugcapsule-compose:0.4.1-beta.5") // if you use Compose
androidTestImplementation("io.github.bugcapsule:bugcapsule-android-replay:0.4.1-beta.5")
}
// Application.onCreate, first thing
BugCapsule.init(this,
BugCapsuleConfig.builder()
.mode(CaptureMode.QA)
.backend("https://bugcapsule.example.com", BuildConfig.BUGCAPSULE_INGEST_KEY) // bci_ only
.gitSha(BuildConfig.BUGCAPSULE_GIT_SHA)
.build(),
listOf(okHttp, navigation, BugCapsuleSharedPreferences.builder().allowFile("shop_prefs").build()))
// OkHttp: BugCapsule is the innermost application interceptor
OkHttpClient.Builder().addInterceptor(AuthInterceptor()).addInterceptor(okHttp.interceptor).build()
// Views and Compose: name actions, track text
BugCapsuleViews.onClick(checkoutButton, "cart.checkout") { viewModel.checkout() }
Button(onClick = rememberBugCapsuleAction("cart.checkout") { viewModel.checkout() }) { Text("Checkout") }
// Package.swift (or File → Add Package Dependencies… in Xcode)
.package(url: "https://github.com/BugCapsule/bug_capsule_ios_sdk.git", exact: "0.4.1-beta.3"),
.product(name: "BugCapsule", package: "bug_capsule_ios_sdk"), // app target
.product(name: "BugCapsuleXCTest", package: "bug_capsule_ios_sdk"), // UI test target
// First line of application(_:didFinishLaunchingWithOptions:) or App.init
import BugCapsule
BugCapsule.start(
BugCapsuleConfig(
mode: .qa,
backend: BugCapsuleBackendConfig(url: "https://bugcapsule.example.com", ingestKey: "bci_...")),
integrations: [
BugCapsuleURLSession(rules: [EndpointRule("POST", "/api/checkout", ignoreBodyFields: ["nonce"])]),
BugCapsuleUserDefaults(keys: ["cart_cache"], prefixes: ["settings."]),
BugCapsuleNavigation.shared,
BugCapsuleStateIntegration.shared,
])
// Networking: instrument the configuration your URLSession uses
let config = URLSessionConfiguration.default
BugCapsule.instrument(config)
// UIKit and SwiftUI: name actions, track text
Button("Checkout", action: BugCapsule.action("cart.checkout") { model.checkout() })
TextField("Coupon", text: BugCapsule.trackedText("cart.coupon", $model.coupon))
# Install the published beta packages
npm install @bugcapsule/web@0.4.0-beta.3 @bugcapsule/react@0.4.0-beta.3
npm install -D @bugcapsule/web-replay@0.4.0-beta.3 # only where you run bugcapsule run / verify
// main.ts: await init before rendering
import { BugCapsule, networkIntegration, historyIntegration, localStorageIntegration } from '@bugcapsule/web';
await BugCapsule.init({
appVersion: '1.4.0',
mode: 'qa',
gitSha: import.meta.env.VITE_BUGCAPSULE_GIT_SHA,
backend: { url: 'https://bugcapsule.example.com', ingestKey: 'bci_...' },
integrations: [
networkIntegration({ rules: [{ method: 'POST', path: '/api/checkout', ignoreBodyFields: ['nonce'] }] }),
historyIntegration(),
localStorageIntegration({ allowPrefixes: ['shop.'] }),
],
allowReplay: import.meta.env.DEV,
});
renderApp();
// React: actions, route events, error boundary, QA capture button
<button onClick={BugCapsule.action('cart.checkout', checkout)} data-bugcapsule-action="cart.checkout">
<BugCapsuleRouteListener /> <BugCapsuleErrorBoundary>…</BugCapsuleErrorBoundary> <BugCapsuleCaptureButton />
The CLI runs on macOS, Linux and Windows without Dart or Flutter. Install with Node.js 20+, or use a standalone binary.
npm install -g @bugcapsule/cli@0.4.0-beta.3
bugcapsule login --url https://api.bugcapsule.com --token bcp_...
bugcapsule list # capsules on the backend
bugcapsule inspect <id|file|share-url> # failure, eligibility, network, timeline
bugcapsule run <id> -d "iPhone 18 Pro" -n 3 # replay on the capsule's commit
bugcapsule run <id> --runtime android -n 3 # flutter | android | ios | web, or from bugcapsule.json
bugcapsule verify <id> -n 5 # replay on your working tree
bugcapsule regress add <id> && bugcapsule regress run # exit 1 on failure, for CI
bugcapsule share <id> # expiring public link
bugcapsule capture --on | --off | --sample-rate 0.05 # kill switch and sampling
Safety and security
Capture runs inside your users' app, so the SDK is designed to fail quietly and stop on command.
Tokens, JWTs, keys, card numbers and sensitive headers are scrubbed before anything is stored or uploaded. Passwords and fields you mark sensitive never leave the device.
One command stops capture everywhere. Devices stop recording and delete queued captures, even offline. Sampling and size limits keep overhead bounded.
If capture fails, your app starts without it, and SDK errors never reach your handlers. Release builds can't enter replay mode.
Scoped ingest keys, expiring share links and per-project retention. Read how data is handled.
FAQ
Something missing? Ask us directly.
An application monitoring, reproduction and verification platform for mobile and web teams. BugCapsule groups issues, tracks release health and performance, and captures supported actions, network responses and state that led to a failure. QA context and MCP repair tasks connect that evidence to your team’s coding agents. The bugcapsule CLI replays supported recordings against your real app code so you can reproduce the bug, verify a fix and keep it as a regression test.
Flutter, native Android (Kotlin or Java), native iOS (Swift, iOS 15+) and the web, with React helpers. Replay runs on iOS simulators, Android emulators and Chromium, using the runtime that captured the capsule. See the feature matrix for coverage by platform.
Create a workspace, generate an SDK token in Project settings and add the SDK and capture integrations to your app. Install the CLI with npm on Node.js 20+, or download a standalone binary, then run bugcapsule login to sign in through your browser. The CLI runs on macOS, Linux and Windows without Dart or Flutter; replay needs the build tools for your app, including Xcode on macOS for iOS. Follow the quickstart and CLI setup.
Replay re-runs your actual app with recorded inputs and responses, so you can debug the failure against your code. The dashboard lets you inspect the capsule and copy replay commands; execution happens locally with the CLI or in CI. The interactive demo illustrates this workflow with sample data.
Yes, through supported integrations: WebSocket adapters across all four runtimes, allowlisted Flutter platform channels, and native SDK adapter APIs for Flutter, Android and iOS. Flutter pilot adapters cover selected Firebase, location, Google Maps and Stripe operations; their coverage is partial and tested against fakes or scripted platforms. Replay uses recorded interactions offline and requires compatible adapters in the build. See the coverage details before integrating.
Add the optional bug_capsule_native plugin to report native crashes, Android ANRs and iOS app hangs alongside Dart errors. On iOS it requires Flutter Swift Package Manager; CocoaPods alone does not enable native crash reporting. Upload release symbols for readable native stack traces. See the native crash setup.
BugCapsule supports crash and error reporting, release health, performance, alerts and user feedback. Point a supported Sentry SDK at your project’s Sentry-compatible DSN to send events to BugCapsule, then add the BugCapsule SDK for replay capture. It does not replace profiling, session-replay video or cron monitoring. On the web it can also run alongside Sentry and link events to capsules. See the migration guide.
Every requested verify attempt completed faithfully and the original failure did not fire. Missing adapters, unavailable payloads or mismatched interactions cannot count as a clean verification. One clean attempt and one error is INCONCLUSIVE, never FIXED. The result applies to that recorded scenario, not every possible path through your app. See verification verdicts.
Yes. Add a capsule with bugcapsule regress add, then run bugcapsule regress run against your working tree locally or in CI. The suite checks whether recorded failures return and reports invalid or incompatible runs separately from passing tests. See the CI guide.
Redaction runs on the device before upload. You can exclude endpoints, control network body capture and add your own redaction rules. Interaction payload controls vary by platform and adapter; missing or redacted values may prevent faithful replay. Inspect real capsules before widening a rollout and follow the capture privacy guide.
Yes, with Emergency Recovery, once your app is built with a supported SDK. It needs the next Flutter, Android and iOS SDK releases. A signed policy can block a feature, make it read-only, show a message or ask for an update. Guards don't run new code, and a modified app can skip them, so anything that moves money or data should also be refused by your server. Read the guide.
In early access, and only for logic and layouts your app registered as patchable when it was built. Native code, plugins, permissions and anything unregistered still need a store release. The patch runtime isn't in the public SDKs yet, and no app store has reviewed this feature, so check the rules of your distribution channel. Ask us about access.
Replay runs on simulators, emulators and Chromium, not physical devices. Database snapshots such as SQLite and Core Data, uninstrumented dependencies and unsupported native operations are not covered. WebSocket and native integrations have their own limits; a missing adapter or a connection that cannot be restored can make a capsule incompatible. Check the known limitations and inspect a capsule’s dependency coverage before replaying it.
Create a workspace, connect your app and bring monitoring, replay and verification into your team’s workflow.
Beta support from the people who wrote the code: contact@bugcapsule.com. We reply within one business day.