A Chrome-DevTools-style console for your Flutter app. Buoy Console captures every print, debugPrint, and log call — plus FlutterError reports and uncaught async errors — and shows them in a familiar, filterable panel: on your phone, on the desktop dashboard, or through your AI agent.
The React Native build of this tool, running here on mock data. The Flutter port ships the same panels — walk the tour, or skip it and start tapping.
Not a video — this is the shipped console running on mock logs. console.log, warn and error stream in on the device. No Metro terminal, no cable.
flutter pub add buoy_consoleTo capture print, wrap your entry point in BuoyConsole.runZoned (a Zone is the only way to observe print in Dart) — so capture starts before your first log fires:
import 'package:buoy_console/buoy_console.dart';
void main() {
BuoyConsole.runZoned(() {
runApp(const MyApp());
});
}
import 'package:buoy_console/buoy_console.dart';
void main() {
BuoyConsole.runZoned(() {
runApp(const MyApp());
});
}
If you never call BuoyConsole.runZoned, call BuoyConsole.install() once instead — everything except print (debugPrint, FlutterError, uncaught async errors) is still captured.
An uncaught error normally takes the desktop connection down with it: the throttled snapshot never fires, and the dashboard just shows an app that stopped answering. Buoy pushes a crash entry out immediately instead, while the connection is still alive, so the app's last words are readable from the desktop dashboard and from your AI agent (get_triage leads with them).
Crash entries are tagged so you can tell what actually happened:
| Tag | Source | Meaning |
|---|---|---|
[UNCAUGHT] | PlatformDispatcher.onError, guarded zone | Nothing in your code handled this error. |
[RENDER ERROR] | FlutterError.onError | A framework/build error. Flutter fires this for errors an ErrorWidget then recovers from, so it is reported without claiming your app crashed. |
The same crash arriving through two seams is recorded once. Two genuinely separate crashes with the same message are recorded twice — a tool whose job is "the app's last words" shouldn't quietly throw one away.
With the MCP server, an AI agent can read the console tail directly with get_console — filtering by minimum level or message substring to pull just the errors it needs while debugging.
Wrap your entry point in BuoyConsole.runZoned — a Zone is the only way to observe print in Dart — and every print, debugPrint, and log call, plus FlutterError reports and uncaught async errors, appears in a filterable on-device panel in any build.
Yes. An uncaught error normally takes the desktop connection down before the throttled snapshot fires; Buoy pushes a crash entry out immediately while the connection is alive, tagged [UNCAUGHT] or [RENDER ERROR], so the app's last words are readable from the dashboard and from an AI agent.