flutter_dev_monitor 2.5.0 copy "flutter_dev_monitor: ^2.5.0" to clipboard
flutter_dev_monitor: ^2.5.0 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)

Screenshots #

DevMonitor Lab & Overlay Performance Console
Flow Trace Timeline Interactive Route Map Stats & Analytics

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.observer tracks the active route so API logs are grouped by screen.
  • DevMonitor.builder() injects the draggable FPS/RAM overlay automatically.

Overlay configuration options

Customize overlay behavior by passing parameters to DevMonitor.builder():

// Default configuration:
builder: DevMonitor.builder(),

// Custom options:
builder: DevMonitor.builder(
  showOverlay: true,        // Initial visibility (default: true)
  enableSnapToEdge: true,   // Snap to nearest screen edge on drag release (default: true)
  tuckedByDefault: false,   // Start initialised as a small side-handle (default: false)
  alwaysHideToEdge: false,  // Auto-tuck into side-handle on drag release (default: false)
),
  • showOverlay: Initial visibility. Set false for release/QA builds where overlay should only be shown on demand.
  • enableSnapToEdge: When true, releasing after dragging snaps the badge to the left/right screen edge. Set to false for free placement anywhere on screen.
  • tuckedByDefault: When true, overlay starts initialised tucked as a small side-handle on the screen edge.
  • alwaysHideToEdge: When true, overlay automatically tucks into the side handle whenever dragging is released.

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()
expandedByDefault bool false Initial overlay expansion mode (expanded panel or pill badge)
enableSnapToEdge bool true When true, automatically snaps overlay to nearest screen edge on drag release
tuckedByDefault bool false When true, initializes overlay hidden as a small handle at the screen edge
alwaysHideToEdge bool false When true, automatically tucks into the side handle every time drag is released

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 kDebugMode or kProfileMode checks before releasing to production.
  • The package uses a MethodChannel for native RAM and disk data. Native implementations are included for Android (Kotlin) and iOS (Swift).
  • Supports Android and iOS only (not web or desktop).
3
likes
140
points
774
downloads
screenshot

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

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.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

dio, flutter, share_plus

More

Packages that depend on flutter_dev_monitor

Packages that implement flutter_dev_monitor