Setting Up the App Debugger
ProWhat you'll learn
- Generating the App Debugger overlay with the Impl + Noop pattern
- Wiring the overlay into
MaterialApp.router - Using
build_prepareto strip the debugger from release builds - Exploring the built-in painter flags and debug pages
- Extending the overlay with sub-bricks
Prerequisites
- An existing Archipelago monorepo (see Monorepo Scaffolding)
- Network SDK generated if you plan to add the network sub-brick (see Network SDK Setup)
Step 1: Generate the App Debugger
archipelago generate app_debuggerThere are no generation variables — the brick produces the same structure for every project.
Step 2: Understand the Generated Structure
App Debugger uses the Impl + Noop pattern. Unlike infrastructure SDKs (monitoring, analytics), the debugger is a standalone debug/noop pair without a shared _api package — it is never consumed by other feature packages, only by the shell app.
features/app_debugger/
├── app_debugger/ # Real implementation — debug overlay, painter flags, built-in pages
└── app_debugger_noop/ # No-op — all methods are empty, zero overhead in releaseThe shell app imports one of these two packages. build_prepare controls which one is resolved at compile time.
Step 3: Configure build_prepare
# build_prepare.yaml
build_prepare:
mappings:
- debug: app_debugger
release: app_debugger_noopRun before building:
# Development build — real overlay
dart run monorepo_toolkit build-prepare debug
# Release build — noop, zero overhead
dart run monorepo_toolkit build-prepare releaseNo runtime if (kDebugMode) checks needed. The noop variant compiles to nothing.
Step 4: Wire the Overlay into MaterialApp
The debugger overlay must wrap the entire widget tree. Pass it through MaterialApp.router's builder parameter:
import 'package:app_debugger/app_debugger.dart'; // or app_debugger_noop
void main() async {
await bootstrap();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
final debuggerSdk = GetIt.instance<AppDebuggerSDK>();
return MaterialApp.router(
routerConfig: appRouter.config(),
builder: (context, child) =>
debuggerSdk.overlay(child: child ?? const SizedBox.shrink()),
);
}
}In debug builds, a floating action button appears on screen. Tap it to open the debug panel. In release builds, debuggerSdk.overlay is the noop passthrough — child is returned unchanged.
Step 5: Register the Feature
In your shell app's bootstrap.dart:
import 'package:app_debugger/app_debugger.dart';
FeatureRegistry.register(AppDebuggerImpl());Step 6: Explore the Painter Flags
The debug panel ships with 10 Flutter rendering flags you can toggle at runtime without rebuilding:
| Flag | What it shows |
|---|---|
repaintRainbow | Flashes widgets with random colours on each repaint |
paintBaselines | Draws text baseline guides |
paintLayerBorders | Outlines compositing layer boundaries |
paintPointers | Draws touch pointer positions |
paintSize | Outlines every widget's layout box |
repaintTextRainbow | Highlights text repaints specifically |
disableClipLayers | Removes clip layers (exposes overflow) |
disablePhysicalShapeLayers | Removes shadow/elevation layers |
disableOpacityLayers | Removes opacity layers (finds unnecessary transparency) |
profileBuilds | Logs build counts and durations to the console |
These map directly to Flutter's debugPaint* and RenderingFlutterBinding flags. Enabling repaintRainbow is the fastest way to spot widgets rebuilding more often than they should.
Step 7: Built-in Debug Pages
The overlay includes three pages out of the box, accessible from the debug panel navigation:
- Painter Flags — Toggle all 10 flags described above
- Device Info — OS version, screen dimensions, pixel ratio, locale
- Package Info — App name, package name, version, build number
Step 8: Add Sub-Bricks for More Panels
The App Debugger is designed to be extended. Each sub-brick adds a new panel to the overlay:
| Sub-brick | Panel added |
|---|---|
app_debugger_network | HTTP request/response log (requires Network SDK) |
app_debugger_websocket | WebSocket frame inspector |
app_debugger_analytics | Analytics event stream viewer |
app_debugger_feature_flag | Live feature flag overrides |
app_debugger_storage | SharedPreferences and secure storage browser |
Generate them individually after the base debugger is set up:
archipelago generate app_debugger_network
archipelago generate app_debugger_storageEach sub-brick registers its own panel automatically via the feature registry — no manual wiring required.
Next Steps
- Add the network panel to inspect HTTP traffic in the overlay
- Add the storage panel to browse and edit persisted values at runtime
- Set up App Blackbox for production session recording (Enterprise tier)