Flutter BlackBox 🐞

pub package License: MIT

An all-in-one In-App Debug & QA Overlay for Flutter. One unified package to monitor network requests, inspect storage, track widget rebuilds, observe Socket.IO events, catch crashes, track performance, and generate comprehensive Markdown QA reports — all without modifying your existing code.

Zero Runtime Cost: Designed exclusively for Debug and Profile modes. All debug code compiles out of Release builds via kDebugMode.

Zero Optional Dependencies: BlackBox ships with no bundled adapter packages. The CLI generates only the adapters your project actually uses — you don't get dio installed if you only use http.

Observe Only, Never Modify: BlackBox hooks into your existing libraries (Dio, http, Socket.IO, SharedPreferences) through their built-in extension points. Your trusted code stays completely untouched.


🚀 Features

Panel Description
🌐 Network Real-time HTTP/Dio request interception. Headers, payloads, status codes, error types (Timeout, Connection, Server).
🎛 Mocking Intercept and replace API calls with local JSON responses. Simulate slow networks with throttle slider.
📋 Logs Auto-captures all debugPrint and print output. Manual logging with levels and tags.
⚡ Performance Live FPS graph, jank detection, memory alerts.
🔄 Rebuilds Track widget rebuild counts — auto-detect ALL rebuilds or wrap specific widgets. Heat-colored ranking.
💾 Storage Inspect, search, edit, and delete key-value pairs from SharedPreferences, GetStorage, Hive, or any storage. Sensitive data auto-redacted.
🔌 Socket IO Auto-capture all incoming Socket.IO events via adapter. Zero code changes.
📱 Device Device info, OS version, app version, connectivity status.
🐛 Crashes Auto-catches framework errors, async exceptions, and unhandled crashes.
🗺️ Journey Route changes and UI interactions logged to reconstruct what happened before a crash.
📝 QA Reports One-tap Markdown reports with screenshots, device state, journey, network logs, and stack traces.

📦 Installation

dependencies:
  flutter_blackbox: ^0.3.0

BlackBox ships with a built-in CLI tool that reads your pubspec.yaml, detects which libraries you already use, and generates the exact adapter code you need — directly into your project.

Why CLI-generated adapters?

BlackBox supports Dio, http, Socket.IO, and SharedPreferences. Rather than forcing all of those packages onto every user, BlackBox generates the adapter implementations into your project. You get only what you use — zero bloat.

flutter_blackbox     → 63 KB, zero optional deps
your project         → gets only the adapters you need

Usage

# Step 1: Add BlackBox
flutter pub add flutter_blackbox

# Step 2: Detect & generate adapters
dart run flutter_blackbox:init --generate

This creates lib/blackbox_adapters.dart tailored to your project:

🐞 BlackBox Init — Auto-detecting your dependencies...

✅ Found dio → Dio HTTP client
⬚  http → not found, skipping
⬚  socket_io_client → not found, skipping
✅ Found shared_preferences → SharedPreferences

✨ 2 adapter(s) detected!

📝 Generated: lib/blackbox_adapters.dart

Step 3: Use in main.dart

import 'package:flutter/foundation.dart';
import 'package:flutter_blackbox/flutter_blackbox.dart';
import 'blackbox_adapters.dart'; // ← generated by CLI

final dio = Dio();

void main() {
  BlackBox.setup(
    httpAdapters: [DioBlackBoxAdapter(dio)],
    storageAdapters: [SharedPrefsStorageAdapter()],
    logAdapter: PrintLogAdapter(),
    trigger: const BlackBoxTrigger.floatingButton(),
    enabled: kDebugMode,
  );
  runApp(const BlackBoxOverlay(child: MyApp()));
}

All CLI options

Command Description
dart run flutter_blackbox:init Detect dependencies and print setup code
dart run flutter_blackbox:init --generate Generate lib/blackbox_adapters.dart
dart run flutter_blackbox:init --help Show all supported libraries

Tip: Re-run --generate any time you add a new library (e.g., add socket_io_client) to regenerate the adapter file.


🛠 Quick Start (no adapters needed)

Core features work with zero adapters — just wrap your app:

import 'package:flutter_blackbox/flutter_blackbox.dart';

void main() {
  BlackBox.setup(
    trigger: const BlackBoxTrigger.floatingButton(),
    enabled: kDebugMode,
  );
  runApp(const BlackBoxOverlay(child: MyApp()));
}

This gives you: logs, crashes, FPS, widget rebuilds, device info, and QA reports out of the box.


🌐 Network Adapters

After running dart run flutter_blackbox:init --generate, your lib/blackbox_adapters.dart contains the adapter class for your HTTP client. BlackBox observes your calls silently — zero changes to your API code.

Dio

import 'blackbox_adapters.dart';

final dio = Dio();

BlackBox.setup(
  httpAdapters: [DioBlackBoxAdapter(dio)],
);

// Use dio exactly as before — BlackBox observes via interceptors
final response = await dio.get('/api/users');

http package

import 'blackbox_adapters.dart';

final adapter = HttpBlackBoxAdapter();

BlackBox.setup(
  httpAdapters: [adapter],
);

// Use the observing client for your HTTP calls:
final response = await adapter.client.get(Uri.parse('https://api.example.com'));

🔌 Socket.IO Adapter

Auto-captures all incoming Socket.IO events with zero code changes:

import 'blackbox_adapters.dart';

final socket = io.io('http://localhost:3000');

BlackBox.setup(
  socketAdapters: [SocketIOBlackBoxAdapter(socket)],
);

// Your existing socket code — completely untouched:
socket.on('message', (data) => handleMessage(data));
// ↑ All events appear in the Socket IO panel automatically

💾 Storage Inspector

SharedPreferences (generated by CLI)

import 'blackbox_adapters.dart';

BlackBox.setup(
  storageAdapters: [SharedPrefsStorageAdapter()],
);

Custom adapter (GetStorage, Hive, FlutterSecureStorage, etc.)

Implement BlackBoxStorageAdapter directly — no CLI needed:

class GetStorageAdapter extends BlackBoxStorageAdapter {
  final GetStorage _box;
  GetStorageAdapter(this._box);

  @override String get name => 'GetStorage';
  @override Future<Map<String, dynamic>> readAll() async { ... }
  @override Future<void> write(String key, dynamic value) async => _box.write(key, value);
  @override Future<void> delete(String key) async => _box.remove(key);
  @override Future<void> clear() async => _box.erase();
}

// Use multiple adapters — each gets its own tab
BlackBox.setup(
  storageAdapters: [
    SharedPrefsStorageAdapter(),
    GetStorageAdapter(GetStorage()),
  ],
);

🔒 Privacy & Sensitive Data

By default, sensitive keys are auto-redacted. Keys matching patterns like password, token, secret, jwt, pin, auth, etc. show as •••••••• — can't be copied or edited.

// Default: sensitive data is hidden (recommended)
BlackBox.setup(storageAdapters: [SharedPrefsStorageAdapter()]);

// Opt-in to show everything (internal dev builds only)
BlackBox.setup(
  storageAdapters: [SharedPrefsStorageAdapter()],
  redactSensitiveData: false,
);

Customize per adapter:

class MyAdapter extends BlackBoxStorageAdapter {
  @override
  List<String> get sensitiveKeyPatterns => [
    ...BlackBoxStorageAdapter.defaultSensitivePatterns,
    'credit_card',
    'bank_account',
  ];
}

🔄 Widget Rebuild Tracker

Track which widgets rebuild the most — find performance bottlenecks.

Toggle AUTO ON in the Rebuilds panel — tracks ALL widget rebuilds automatically using Flutter's debugPrintRebuildDirtyWidgets. Zero code changes needed.

// Or enable programmatically:
BlackBox.startRebuildTracking();

Manual mode (specific widgets)

RebuildTracker(
  label: 'ProductCard',
  child: ProductCard(),
)

Release Safety: RebuildTracker uses kDebugMode (compile-time constant) — eliminated by Dart's tree-shaker in release builds.


📋 Custom Logging

BlackBox.log('User tapped checkout', level: LogLevel.info, tag: 'Checkout');
BlackBox.log('Payment failed', level: LogLevel.error, tag: 'Payment', data: {'orderId': '123'});

BlackBox automatically captures all debugPrint and print output — no manual logging required.


🎛 API Mocking

BlackBox.mock(
  pattern: '/api/v1/user/profile',
  method: 'GET',
  response: MockResponse(
    statusCode: 200,
    body: {'name': 'Alice', 'role': 'Admin'},
  ),
);

🎮 Panel Triggers

BlackBox.setup(
  trigger: BlackBoxTrigger.shake(),                           // Shake device
  // trigger: BlackBoxTrigger.hotkey(LogicalKeyboardKey.f12), // Desktop F12
  // trigger: BlackBoxTrigger.floatingButton(),               // Floating button
);

⚙️ Full Setup Example

import 'package:flutter/foundation.dart';
import 'package:flutter_blackbox/flutter_blackbox.dart';
import 'blackbox_adapters.dart'; // generated by: dart run flutter_blackbox:init --generate

final dio = Dio();

void main() {
  BlackBox.setup(
    // Network — observe silently
    httpAdapters: [DioBlackBoxAdapter(dio)],

    // Socket — auto-capture incoming events
    // socketAdapters: [SocketIOBlackBoxAdapter(socket)],

    // Storage — inspect key-value stores
    storageAdapters: [SharedPrefsStorageAdapter()],

    // Logging
    logAdapter: PrintLogAdapter(),

    // Privacy — sensitive keys auto-redacted (default: true)
    redactSensitiveData: true,

    // Trigger
    trigger: const BlackBoxTrigger.floatingButton(),

    // Ignore specific noisy widgets from the Rebuild tab
    ignoredRebuildWidgets: ['MyAppThemeWrapper'],

    // Only in debug mode
    enabled: kDebugMode,
  );

  runApp(const BlackBoxOverlay(child: MyApp()));
}

💡 Tip: Run dart run flutter_blackbox:init --generate to auto-generate this setup based on your project's dependencies.


📝 QA Reports

Tap the QA tab → provide a bug name → tap Generate Report. BlackBox compiles a Markdown report with:

  • 📸 Screenshot
  • 📱 Device info (OS, model, DPI, connectivity)
  • 🗺️ User journey (routes + taps)
  • 🌐 Failed network requests
  • 🔌 Socket events
  • 📋 Recent logs
  • 🐛 Crash stack traces

One tap Copy → paste directly into GitHub Issues, Jira, or Slack.


🔄 Migration Guide

Upgrading from v0.2.x → v0.3.0

1. Rename: devkit_*blackbox_*

All classes, files, and observers were renamed from devkit to blackbox branding.

v0.2.x (old) v0.3.0 (new)
DevkitOverlay BlackBoxOverlay
DevkitTrigger BlackBoxTrigger
DevKit.setup(...) BlackBox.setup(...)
DevkitNavigatorObserver BlackBoxNavigatorObserver
DevkitGestureObserver BlackBoxGestureObserver
DevkitReport BlackBoxReport
DevkitLogAdapter BlackBoxLogAdapter
PrintLogAdapter PrintLogAdapter ✅ unchanged

Quick find & replace in your project:

DevKit.    →  BlackBox.
Devkit     →  BlackBox
devkit_    →  blackbox_

2. Adapter imports — old barrel files removed

In v0.2.x, adapters were imported from barrel files inside the package:

// ❌ v0.2.x — these files no longer exist
import 'package:flutter_blackbox/adapters/dio.dart';
import 'package:flutter_blackbox/adapters/http.dart';
import 'package:flutter_blackbox/adapters/socket_io.dart';
import 'package:flutter_blackbox/adapters/shared_prefs.dart';

In v0.3.0, run the CLI to generate the adapters into your own project:

dart run flutter_blackbox:init --generate

Then import from the generated file:

// ✅ v0.3.0 — generated into your project
import 'blackbox_adapters.dart';

Your BlackBox.setup() call stays exactly the same — only the import line changes.


3. Full before / after example

v0.2.x (old)

import 'package:flutter_blackbox/flutter_blackbox.dart';
import 'package:flutter_blackbox/adapters/dio.dart';
import 'package:flutter_blackbox/adapters/shared_prefs.dart';

void main() {
  DevKit.setup(
    httpAdapters: [DioBlackBoxAdapter(dio)],
    storageAdapters: [SharedPrefsStorageAdapter()],
    trigger: const DevkitTrigger.floatingButton(),
    enabled: kDebugMode,
  );
  runApp(const DevkitOverlay(child: MyApp()));
}

v0.3.0 (new)

import 'package:flutter_blackbox/flutter_blackbox.dart';
import 'blackbox_adapters.dart'; // dart run flutter_blackbox:init --generate

void main() {
  BlackBox.setup(
    httpAdapters: [DioBlackBoxAdapter(dio)],
    storageAdapters: [SharedPrefsStorageAdapter()],
    trigger: const BlackBoxTrigger.floatingButton(),
    enabled: kDebugMode,
  );
  runApp(const BlackBoxOverlay(child: MyApp()));
}

Navigator observer if you use it:

// v0.2.x
navigatorObservers: [DevKit.journeyObserver]

// v0.3.0
navigatorObservers: [BlackBox.journeyObserver]

4. Migration checklist

  • Run dart run flutter_blackbox:init --generate to create lib/blackbox_adapters.dart
  • Replace all DevKit.BlackBox.
  • Replace all Devkit class names → BlackBox equivalents (see table above)
  • Replace adapter imports with import 'blackbox_adapters.dart';
  • Replace DevkitOverlayBlackBoxOverlay in runApp()
  • Run dart analyze to catch any remaining references

📄 License

MIT.

Libraries

adapters/dio
⚠️ DEPRECATED — This file is no longer shipped with flutter_blackbox.
adapters/http
⚠️ DEPRECATED — This file is no longer shipped with flutter_blackbox.
adapters/shared_prefs
⚠️ DEPRECATED — This file is no longer shipped with flutter_blackbox.
adapters/socket_io
⚠️ DEPRECATED — This file is no longer shipped with flutter_blackbox.
flutter_blackbox
Flutter BlackBox — In-app debug & QA overlay for Flutter.