In Flutter, what are service extensions, and why are some available in profile mode but none in release?
answer
- named hooks tools call
- registerBoolServiceExtension
- assert block: debug only
- if (!kReleaseMode): debug and profile
- performance overlay survives in profile
basics
~20 sService extensions are named hooks the app registers with the Dart VM service so DevTools and the flutter tool can query or toggle it. Debug registers all, profile keeps measurement ones such as the performance overlay, and release registers none.
solid answer
~40 sA service extension is a named hook, registered by the framework's bindings with `registerServiceExtension` or `registerBoolServiceExtension`, that tools call over the VM service to dump the widget tree, toggle debug painting or show the performance overlay. The build mode controls which exist: extensions registered inside an `assert` block exist only in debug, those inside `if (!kReleaseMode)` exist in debug and profile, and release registers none. So profile keeps observation hooks such as `showPerformanceOverlay`, `debugDumpApp` and build profiling, while debug-only ones such as `debugPaint`, the DEBUG banner toggle and the inspector's extensions are gone. Release drops them all for size, safety and representative behaviour.
go deeper
Know that DevTools toggles work by calling hooks inside the app, and that release builds have none of them.
Explain how the framework registers extensions per mode, assert blocks for debug and !kReleaseMode for debug and profile.
Use the right mode for each tool, profile for the overlay and timeline, debug for painting and the inspector, and plan release diagnostics without them.
Consider which custom diagnostics an app should expose in internal builds and ensure none leak into what users install.
## What a service extension is A **service extension** is a named hook that a Flutter app registers with the Dart VM service so that tools can call into the running app. DevTools, IDE plugins and the `flutter` tool use them to read information (for example a text dump of the widget tree) or flip settings (for example debug painting or the performance overlay) without changing your code. The framework registers them through methods such as `registerServiceExtension` and `registerBoolServiceExtension` on its bindings, under names like `ext.flutter.<name>`. Every toggle you click in DevTools that changes how the app draws or reports itself is, underneath, a service extension call. ## Which exist in which mode The build mode decides which extensions are registered. The framework code shows the pattern clearly: - Extensions registered inside an **`assert(() { ... }())` block** exist only in **debug** builds. - Extensions registered inside **`if (!kReleaseMode)`** exist in **debug and profile**. - **Release** registers none, and the docs list "service extensions are disabled" among release mode's properties. | Extension (examples from `WidgetsBinding` and `RendererBinding`) | Debug | Profile | Release | |---|---|---|---| | `showPerformanceOverlay` | Yes | Yes (not on the web) | No | | `debugDumpApp` (widget tree as text) | Yes | Yes | No | | `profileWidgetBuilds` (build events on the timeline) | Yes | Yes | No | | `debugAllowBanner` (the DEBUG banner toggle) | Yes | No | No | | `debugPaint`, `repaintRainbow` | Yes | No | No | | Widget inspector extensions | Yes | No | No | This matches the docs' description of profile mode: some service extensions, such as the one that enables the performance overlay, stay enabled so that performance can be observed. ## Why they are removed from release 1. **Size and speed.** The registration code, and in the `assert` case the closures themselves, are compiled out. 2. **Security and privacy.** A release app should not let an external tool dump its widget tree or change its behaviour. 3. **Representative behaviour.** Debug-only switches like debug painting change what is drawn; they must not be reachable in the build users run. ## What this means in practice - **DevTools features vary by mode.** Connect DevTools to a profile build and the widget inspector's debug tools are missing; that is expected, not a broken connection. - **The performance overlay** can be switched on from tools in profile mode, where its numbers mean something; on the web it is not registered. - **Release diagnostics** must come from your own logging and crash reporting, because there is no VM service connection to query. ## Using them from the flutter tool The `flutter run` terminal exposes several extensions as single keys, and the tool itself respects the mode: - `p` toggles debug painting, and the tool only sends it when the app runs in **debug** mode. - `P` toggles the performance overlay, which works in **debug and profile** runs. - `a` toggles widget build profiling, which records builds as timeline events. Seeing `p` do nothing in a profile run is therefore expected behaviour, not a broken session. ## Relationship to other debug tools Service extensions are one layer of the debug tooling. The VM service connection they run over, logging, breakpoints and the inspector's panels are separate topics; what belongs to build modes is **which of these hooks exist in each mode and why**.
- Why can't you toggle debug painting on a profile build from DevTools?The `debugPaint` extension is registered inside an `assert` block in `RendererBinding`, so it exists only in debug builds. Profile keeps measurement hooks such as the performance overlay, not tools that change what is drawn.
saying these in an interview costs you the question
- Service extensions are DevTools plugins installed on the developer machine.
- Release builds keep the performance overlay extension for production monitoring.
- Profile mode has exactly the same extensions as debug mode.
- A missing inspector toggle in profile means DevTools failed to connect.