flutter_dev_monitor 2.2.1
flutter_dev_monitor: ^2.2.1 copied to clipboard
In-app developer monitor for Flutter apps. Tracks API calls, FPS, RAM, and disk usage with a floating overlay and full dashboard. Framework-agnostic — works with GetX, Provider, Riverpod, or plain Flutter.
flutter_dev_monitor #
An in-app developer monitor for Flutter. Tracks API calls, FPS, RAM, and disk usage with a floating overlay and a full dashboard — framework-agnostic, works with GetX, Provider, Riverpod, or plain Flutter.
Features #
- Floating HUD — draggable overlay showing live FPS, GPU ms, build ms, RAM, and network ping
- API log — captures every Dio request: URL, method, status code, duration, caller function, and screen
- OPEN / ACTION phases — automatically separates APIs that ran when the screen opened (OPEN) from those triggered by user actions (ACTION); each visit creates a fresh OPEN group
- FPS chart — per-screen frame-time history with avg/min/max stats
- RAM chart — per-screen memory history with avg/min/max stats
- Hardware grid — RAM / disk usage updated every 3 seconds
- Error capture — catches Flutter and Dart unhandled errors with stack traces
- Route log — records every push / pop / replace with timestamp
- Screen-aware — data is scoped per route; up to 50 screens tracked (LRU eviction)
Getting started #
Add the package to your pubspec.yaml:
dependencies:
flutter_dev_monitor: ^1.3.0
dio: ^5.9.0 # required for MonitorInterceptor
Setup #
1. Add the Dio interceptor #
final dio = Dio()..interceptors.add(DevMonitor.interceptor);
All requests made through this Dio instance are automatically captured.
2. Configure MaterialApp #
MaterialApp(
navigatorObservers: [DevMonitor.observer],
builder: DevMonitor.builder(), // overlay visible by default
home: const HomeScreen(),
)
DevMonitor.observertracks the active route so API logs are grouped by screen.DevMonitor.builder()injects the draggable FPS/RAM overlay automatically.
Overlay visibility
By default the overlay is always visible. Pass showOverlay: false to start hidden — useful for production builds where you only want the overlay on demand:
// Always visible (default):
builder: DevMonitor.builder(),
// Hidden until toggled (e.g. release / QA builds):
builder: DevMonitor.builder(showOverlay: false),
Toggle at runtime from anywhere:
DevMonitor.showOverlay();
DevMonitor.hideOverlay();
DevMonitor.toggleOverlay();
Or wrap any widget (logo, version label, etc.) with a secret N-tap trigger:
DevMonitor.tapToToggle(
tapCount: 7, // default
clipboardKey: 'dev', // optional: copies to clipboard on trigger
child: myLogoWidget,
)
3. Open the dashboard #
Navigate to MonitorDashboardPage from anywhere — a button in your AppBar works well:
IconButton(
icon: const Icon(Icons.bar_chart),
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
settings: const RouteSettings(name: '/MonitorDashboardPage'),
builder: (_) => const MonitorDashboardPage(
initialScreen: '/HomeScreen',
),
),
),
)
Full example #
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_dev_monitor/flutter_dev_monitor.dart';
final dio = Dio(BaseOptions(baseUrl: 'https://jsonplaceholder.typicode.com'))
..interceptors.add(DevMonitor.interceptor);
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
navigatorObservers: [DevMonitor.observer],
builder: DevMonitor.builder(),
home: const HomeScreen(),
);
}
}
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
@override
void initState() {
super.initState();
dio.get('/posts'); // captured automatically — appears as OPEN
dio.get('/users'); // captured automatically — appears as OPEN
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Home'),
actions: [
IconButton(
icon: const Icon(Icons.bar_chart),
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
settings: const RouteSettings(name: '/MonitorDashboardPage'),
builder: (_) => const MonitorDashboardPage(
initialScreen: '/HomeScreen',
),
),
),
),
],
),
body: Center(
child: ElevatedButton(
onPressed: () => dio.get('/posts/1'), // appears as ACTION
child: const Text('Refresh'),
),
),
);
}
}
A runnable example with multiple screens and refresh simulation is in the example/ directory.
Usage with state management #
Provider / plain Flutter #
// MonitorController.instance is a singleton ChangeNotifier.
final fps = MonitorController.instance.currentFps;
GetX #
Get.put(MonitorController.instance);
Riverpod #
final monitorProvider = ChangeNotifierProvider((_) => MonitorController.instance);
API reference #
| Class / Member | Description |
|---|---|
DevMonitor.interceptor |
Singleton MonitorInterceptor — add to your Dio instance |
DevMonitor.observer |
Singleton MonitorNavigatorObserver — pass to navigatorObservers |
DevMonitor.builder({bool showOverlay}) |
Returns a TransitionBuilder for MaterialApp.builder; sets initial overlay visibility |
DevMonitor.appBuilder |
TransitionBuilder — same as builder() with default visibility, kept for backwards compatibility |
DevMonitor.showOverlay() |
Show the overlay at runtime |
DevMonitor.hideOverlay() |
Hide the overlay at runtime |
DevMonitor.toggleOverlay() |
Toggle overlay visibility |
DevMonitor.tapToToggle(...) |
Wraps a widget with a secret N-tap toggle trigger |
MonitorDashboardPage |
Full dashboard — push as a named route |
MonitorController |
Singleton ChangeNotifier with all observable state |
FpsOverlay |
Low-level overlay widget — use DevMonitor.builder() instead |
DevMonitor.builder() parameters #
| Parameter | Type | Default | Description |
|---|---|---|---|
showOverlay |
bool |
true |
Initial overlay visibility; can be changed at runtime via showOverlay()/hideOverlay() |
DevMonitor.tapToToggle() parameters #
| Parameter | Type | Default | Description |
|---|---|---|---|
child |
Widget |
required | Widget to wrap |
tapCount |
int |
7 |
Number of consecutive taps to trigger |
clipboardKey |
String? |
null |
String copied to clipboard on each trigger |
MonitorDashboardPage parameters #
| Parameter | Type | Default | Description |
|---|---|---|---|
initialScreen |
String |
required | Route name of the screen to show on open (e.g. '/HomeScreen') |
Notes #
- Debug / profile only — wrap usage in
kDebugModeorkProfileModechecks before releasing to production. - The package uses a
MethodChannelfor native RAM and disk data. Native implementations are included for Android (Kotlin) and iOS (Swift). - Supports Android and iOS only (not web or desktop).
