Debug Tools
How to set up the App Blackbox session recorder contract in Flutter
Free Reference for app_blackbox: every variable, option and package it generates. Command: archipelago generate app_blackbox
Generate App Blackbox, learn which packages ship per flavor, set platform permissions, strip the recorder from production builds, and capture events.
What you'll learn
- Generating the App Blackbox session recorder with filesystem snapshots and optional screen recording
- Understanding the packages and which ones ship per build flavor
- Configuring platform permissions for Android and iOS
- Using
build_prepareto strip the recorder from production builds - Capturing custom events and retrieving session archives
- Reading the app's startup in the viewer's Launch view
Prerequisites
- An existing Archipelago monorepo (see Monorepo Scaffolding)
- Enterprise subscription, App Blackbox is not available on Free or Pro tiers
App Blackbox vs App Debugger: App Blackbox records a debug/staging session (metrics, filesystem events, optional screen capture) so you can diagnose issues after they occur. The production flavor strips it. App Debugger is an in-app overlay for developers to inspect state live. The two serve different purposes. You can use them together.
Step 1: Generate App Blackbox
archipelago generate app_blackbox_recorderThe brick has one variable, uiKitPackageName, which it reads from archipelago.yaml. It generates its hard dependencies when they are missing:
app_blackbox(the free API and noop packages)app_debuggershared_consentandshared_identifiers
If the launch tracker is installed, the brick also wires its launch trace into the host app. Screen recording and filesystem snapshots are chosen at runtime, per session, through BlackboxConfig:
await recorder.start(
config: const BlackboxConfig(
enableScreenRecording: false, // default
enableFilesystemSnapshots: true, // default
),
);Step 2: Understand the Generated Structure
Two bricks together make six packages:
features/app_blackbox/
├── app_blackbox_api/ # SessionRecorderSDK interface and models (free brick)
├── app_blackbox_noop/ # Inert stub for production flavors (free brick)
├── app_blackbox/ # Orchestrator and debug panel tab (this brick)
├── app_blackbox_filesystem/ # Filesystem snapshot recorder (this brick)
├── app_blackbox_metrics/ # CPU, memory and frame metrics (this brick)
└── app_blackbox_recording/ # Screen recording (this brick)app_blackbox_api defines the contract. Feature code imports only this package. The production flavor swaps app_blackbox for app_blackbox_noop, so no recorder code ships in production. Internal flavors (development, staging, alpha, beta) keep the recorder, also in release mode.
Step 3: Check build_prepare
The post-generation hook adds the app_blackbox to app_blackbox_noop mapping to build_prepare.yaml. It also lists the three capability packages under debug_only. You add nothing by hand.
Run before each build, with the build's own flavor. The generated Fastfile does this for you:
# Internal flavors: the recorder stays
dart run monorepo_toolkit build-prepare --flavor beta
# Production flavor: app_blackbox_noop
dart run monorepo_toolkit build-prepare --flavor production
# Check that nothing leaked
dart run monorepo_toolkit build-prepare --check-leaks --flavor productionThe command rewrites the app_blackbox dependency in the host app's pubspec.yaml. There is no runtime if/else. The noop package exports empty stubs with the same class names, so the injector needs no edit.
Step 4: Configure Platform Permissions
Android
Nothing to add. The recording plugin declares its own foreground-service and notification permissions and its mediaProjection service, and asks for capture permission at each start. The metrics plugin declares its own ACCESS_NETWORK_STATE permission. Production-flavor builds have neither plugin.
iOS
Add to ios/Runner/Info.plist:
<key>NSPhotoLibraryUsageDescription</key>
<string>App Blackbox saves session archives to your photo library.</string>Enable the ReplayKit capability in Xcode under Signing & Capabilities for the Runner target. You need it only if you start sessions with BlackboxConfig(enableScreenRecording: true).
Step 5: Check the Wiring
You write no registration code. The packages declare their modules under archipelago: di_modules, and the host injector imports only package:app_blackbox/app_blackbox.dart.
The hook adds GetIt.I<SessionRecorderSDK>(); at the archipelago:debug_panel_pages marker in app_debugger's lib/src/di/debug_tools.dart. This resolves the recorder at startup, so the Blackbox tab appears in the debug panel. SessionRecorderSDKImpl stays an eager SDK for this reason.
The app test harness picks up the recorder's test prerequisite. Run dart run monorepo_toolkit generate test-harness, then flutter test test/di/injector_test.dart.
Step 6: Record a Session
Recording needs the user's diagnostics consent. Turn on Diagnostics consent in the Blackbox tab of the debug panel, or record the decision from your own consent screen with getIt<ConsentGate>().record(purpose: ConsentPurpose.diagnostics, granted: true). Until then start() throws StateError.
final recorder = getIt<SessionRecorderSDK>();
// Start a session — returns a unique session ID
final sessionId = await recorder.start();
// Capture a custom event at any point
recorder.captureCustomEvent(
'checkout_initiated',
properties: {'amount': 99.99, 'currency': 'IDR'},
);
// Stop the session and retrieve the archive
final archive = await recorder.stop();archive is a BundleArchive. It holds the .bbx ZIP bytes and a suggested file name. The ZIP has the event log, metrics samples, filesystem snapshots and, if enabled, the screen recording. stop() returns null when nothing was recorded or diagnostics consent was withdrawn.
Every stop also saves the bundle on the device. This holds for code, the Blackbox tab and the floating control. The Blackbox tab lists the saved sessions. Each row has Share, Copy path and Delete.
Step 7: View a Session Archive
Use Share on the session row to move the .bbx file to your computer, then open it in the Blackbox Viewer:
https://archipelago.banuacoder.com/blackboxThe viewer renders the event timeline, metrics graphs, and screen replay side by side. The browser processes archives locally. No data goes to Archipelago servers.
Open the Launch view to see how the app started. The recorder adds the launch trace to every bundle when the launch tracker is present. Every generated app has it. The waterfall shows which initializers delayed the first frame. It also shows which ran in parallel and which waited in a queue. The critical path is highlighted. Use it to find the step worth making faster. See The Launch view.
Key Configuration Points
| Customization | Where to Change |
|---|---|
| Snapshot directories | The path list in the snapshot config of app_blackbox_filesystem |
| Metrics sample rate | The collection interval in app_blackbox_metrics |
| Auto-start on launch | Call recorder.start() during post-launch init in bootstrap.dart |
| Upload archive to your backend | After recorder.stop(), POST the archive file via the Network SDK |
Next Steps
- Read the Blackbox guide for the whole flow
- Use the cloud sync guide to upload sessions to your own bucket
- Set up App Debugger for in-development overlay tooling
- Configure monitoring to correlate session IDs with crash reports