sleuth library
Sleuth — Runtime Performance Diagnostics for Flutter
Surfaces performance bottlenecks and actionable fixes directly inside your app using three layers of analysis:
- Frame timing: SchedulerBinding.addTimingsCallback per frame (~zero cost)
- VM timeline (best-effort): vm_service sub-phase breakdowns when connected
- Widget tree scan: structural heuristics for common anti-patterns
Usage
void main() => runApp(Sleuth.track(child: MyApp()));
Features
- 20 performance detectors (VM-powered, hybrid, structural, and runtime)
- Actionable fix hints for every issue
- In-app overlay with live FPS chart and issue dashboard
- Debug mode warning (run with --profile for accurate data)
- Completely disabled in release builds
Theming
The overlay auto-detects dark/light mode from the system brightness and
uses the high-contrast presets when the platform asks for high
contrast. The header toggle cycles System, Light and Dark (persisted in
OverlayUiState.themeMode). To force a specific theme or customize
colors:
// Light theme for light-background apps
Sleuth.track(
child: MyApp(),
config: SleuthConfig(theme: SleuthThemeData.light()),
);
// Custom brand colors
Sleuth.track(
child: MyApp(),
config: SleuthConfig(
theme: SleuthThemeData.light().copyWith(
severityCritical: Color(0xFFDC2626),
),
),
);
// Toggle at runtime (e.g. from app code)
Sleuth.updateTheme(const SleuthThemeData.light());
Sleuth.updateTheme(null); // revert to the config theme or auto-detect
See SleuthThemeData for all available tokens (colors, spacing, typography, and border radii).
Classes
- AiChatAdapter
- Provider-agnostic AI chat adapter.
- AiChatMessage
- A single message in an AI chat conversation.
- AiChatRequest
- Request sent to the AI provider via AiChatAdapter.sendMessage.
- AllocationEntry
- A single class's allocation contribution during heap growth.
- BaseDetector
- Base class for all performance detectors.
- BracketSpec
- One bracket axis declaration for a detector's runtimeVerified evidence.
- CaptureEntry
- A single captured jank frame with its verdict, stamped issues, and timing.
- ComponentMetadata
- Metadata describing how a non-detector component's reliability claim was validated.
- CpuAttribution
- A single function's CPU attribution during a jank frame.
- DebugInstrumentationConfig
- Advanced sub-flag configuration for debug instrumentation.
- DebugSnapshot
- A snapshot of debug callback data accumulated over a time window.
- DetectorMetadata
- Metadata describing how a detector's threshold or heuristic was validated.
- DetectorThresholds
- Detector-specific thresholds for fine-tuning performance detection.
- FixHintBuilder
- Centralised builder for context-aware fix hints.
- FixVerificationResult
- Result of comparing current issues against a captured baseline.
- FpsPercentiles
- FPS percentile values computed from a FrameStatsBuffer.
- FrameBudget
- Per-frame time budget resolved by resolveFrameBudget.
- FrameStats
- A single frame's timing data from SchedulerBinding.addTimingsCallback.
- FrameStatsBuffer
- Circular buffer holding the last capacity frames for live display.
- FrameStatsSummary
- Aggregated frame stats summary for the export.
- FrameVerdict
- A per-frame performance verdict combining SchedulerBinding + VM Timeline.
- GcEventSummary
- A serializable summary of a GC event extracted from VM timeline data.
- HeapSample
- A single heap memory usage sample from the VM service.
- InMemorySleuthStateStore
- A SleuthStateStore that keeps the JSON in memory.
- IssueVerificationEntry
- An individual issue's change between baseline and current state.
- JankCaptureBuffer
- Bounded rolling buffer of worst jank frames.
- NetworkMonitorDetector
- Detects slow, excessive, or oversized HTTP requests.
- OverlayUiState
- Overlay UI state that outlives the widgets showing it.
- PaintOriginInstance
- One widget instance credited as a likely repaint origin.
- PaintOriginStats
- The likely repaint origins of one widget type over a snapshot window.
- ParsedTimelineData
- Parsed timeline data from a batch of VM timeline events.
- PerformanceIssue
- A detected performance issue with actionable fix hint.
- PhaseEvent
- A single VM timeline event with its absolute timestamp and duration.
- PlatformChannelCall
- A completed platform channel call.
- PlatformChannelSummary
- A serializable summary of a platform channel event from VM timeline data.
- PollTimings
- Cost of one VM timeline poll, split by segment.
- ProfileCaptureSchema
- Schema + validator for Sleuth profile-mode captures.
- RebuildDetector
- Detects expensive widget rebuilding using VM BUILD scopes + element tree.
- RecurrenceEntry
- A single observation in a recurrence ring buffer.
- RecurrenceTrend
- Ring-buffered time-series tracker for a single issue's recurrence.
- RequestRecord
- A recorded HTTP request with timing and size metadata.
- RouteSession
- Per-route statistics accumulated while a route is the active scan target.
- ServiceExtensionRegistry
-
Binds
ext.sleuth.*extensions todart:developer. - SessionMarkdownExporter
- Renders a SessionSnapshot as GitHub-flavoured markdown suitable for pasting into Slack, a PR description, or a bug report.
- SessionSnapshot
- A point-in-time snapshot of a sleuth session for export.
- SimpleStructuralDetector
- Convenience base class for writing a structural custom detector without the full BaseDetector boilerplate.
- Sleuth
- Entry point for the Sleuth package.
- SleuthConfig
-
Configuration for
SleuthController. - SleuthStateStore
- Storage for the overlay UI state (trigger position, card geometry, hidden issues, severity filter).
- SleuthThemeData
- All visual tokens for the Sleuth overlay UI.
- StartupMetrics
- Startup performance metrics captured by Sleuth.init.
- StreamResourceDetector
-
Detects likely retained async resources (Stream subscriptions,
StreamControllers, WebSocket channels, optional rxdart Subjects)
via
getAllocationProfileclass-instance diff over a sliding window, gated on a recentMemoryPressureDetector.heap_growingemission. - StreamResourcePollResult
- Diagnostic result of a single allocation-profile poll triggered by StreamResourceDetector.pollAllocationProfileNow. Capture screens log this every poll so an empty K=4 window can be diagnosed without a second 50-second on-device session.
- WidgetHeatMapEntry
- Aggregated performance cost for a single widget across all detectors.
- WidgetHighlight
- A detected widget's screen position and performance status.
Enums
- AiChatRole
- Role in an AI chat conversation.
- CardWindowState
- Window state of the floating issues card.
- ConnectionMode
-
Five-state mode stamped on every
ext.sleuth.*response. Lets a consumer distinguish "no issues observed" from "warmup not elapsed" or "no VM-tier frame verdict yet". - DetectorLifecycle
- Lifecycle classification for detectors.
- DetectorType
- Available detector types for configuration via SleuthConfig.enabledDetectors.
- EvidenceTier
- Evidence tier for a detector's threshold or heuristic.
- FixEffort
- Estimated developer effort to apply the suggested fix.
- FixVerificationStatus
- Categorization of an issue's change between baseline and current state.
- FrameRateSource
- Where the effective frame rate behind a FrameBudget came from.
- InteractionContext
- The user interaction state when an issue was observed.
- IssueCategory
- Categories mapping to Flutter rendering pipeline phases.
- IssueConfidence
- Confidence levels reflecting the strength of evidence behind a detection.
- IssueSeverity
- Severity levels for detected performance issues.
- ObservationSource
- Identifies the data source that produced a detection, so the UI can show provenance and users can understand the strength of the evidence.
- PipelinePhase
- Rendering pipeline phase suspected as bottleneck.
- RebuildCountSource
- Origin of the DebugSnapshot.rebuildCounts data.
- SleuthThemeMode
- Theme mode picked with the overlay header's theme toggle.
- SnapshotSection
-
Payload-bearing sections of a SessionSnapshot JSON envelope that a
consumer can opt out of via projection. Metadata keys
(
schemaVersion,exportedAt,packageVersion,isVmConnected,isDebugMode,suppressedCount) are never projectable — they are small and required for parsing, so they always serialize. - TimelinePhase
- Classifies a raw VM timeline event by rendering pipeline phase.
- TrendDirection
- Trend direction for an issue's recurrence over time.
- TriggerEdge
- Horizontal screen edge the trigger button rests against.
Mixins
- ComponentMetadataProvider
- Mixin that lets a non-detector component declare its validation metadata in a parallel shape to DetectorMetadataProvider.
- DetectorMetadataProvider
- Mixin that lets a detector declare its validation metadata.
Extensions
Constants
- kMcpEnvelopeSchemaVersion → const int
-
MCP envelope shape version. Distinct from
SessionSnapshot.schemaVersion. - kSleuthPackageVersion → const String
-
Stamped on
ext.sleuth.diagnose. Keep in sync withpubspec.yaml.
Functions
-
buildWidgetHeatMap(
List< PerformanceIssue> issues, {int maxEntries = 10}) → List<WidgetHeatMapEntry> -
Build a heat map from a list of issues, filtering out framework widgets
and returning the top
maxEntriesby total ranking score. -
resolveFrameBudget(
{required int fpsTarget, required double displayRefreshRateHz, double? measuredCadenceHz, required bool auto}) → FrameBudget -
Resolves the per-frame budget from
fpsTarget, the display's reported refresh rate, and the measured vsync cadence.
Exceptions / Errors
- AiProviderException
- A failure reported by an AI provider: a non-200 response or an error frame inside the event stream.