The diagonal "DEBUG" banner in the top-right corner of a Flutter app during development is purely cosmetic — it never appears in a real release build regardless, but it's still worth knowing how to hide while taking screenshots or demoing a debug build to a client.
Removing it with a single property
MaterialApp(
debugShowCheckedModeBanner: false,
home: const HomeScreen(),
)
debugShowCheckedModeBanner: false on the top-level MaterialApp widget is the entire fix — it's a boolean flag specifically for this banner, unrelated to any other debug or release configuration.
The equivalent for CupertinoApp
CupertinoApp(
debugShowCheckedModeBanner: false,
home: const HomeScreen(),
)
Apps built with CupertinoApp (Flutter's iOS-styled root widget) instead of MaterialApp have the exact same property, since the banner itself isn't tied to Material Design specifically.
Why it only appears in debug mode in the first place
The banner is automatically excluded from both profile and release builds (flutter run --release or a genuine app store build) — it exists purely as a visual reminder that a currently running build is an unoptimized debug build, not a signal about the app's actual functionality or performance.
A common point of confusion: it's unrelated to actual debug logging
Setting debugShowCheckedModeBanner: false only removes the visual banner — it has no effect on whether the app is actually running in debug mode, on print() statement output, or on debugging tools like breakpoints and the Flutter DevTools inspector, all of which remain fully functional regardless of this one cosmetic setting.
Other debug-only visual indicators worth knowing about
import 'package:flutter/rendering.dart';
// Highlight repainted areas while debugging
debugRepaintRainbowEnabled = true;
// Show layout construction guides
debugPaintSizeEnabled = true;
These are separate debug flags entirely, each toggled independently in code (typically in main()) rather than through a MaterialApp property — worth knowing they exist separately from the debug banner, since disabling one has no effect on the others.
Set the flag on the root app that actually renders your UI
If the banner remains after setting the property, check whether the widget you edited is really the application's root MaterialApp or CupertinoApp. Test harnesses, nested navigators, examples embedded in another app, or a second app widget used for a specific flavor can make it easy to change a MaterialApp that is not the one currently on screen.
Do not use the missing banner as proof of a release build
Because the property can hide the banner while the application is still running in debug mode, screenshots are not evidence of build mode. If code needs to behave differently by mode, Flutter exposes compile-time mode constants such as kDebugMode, kProfileMode, and kReleaseMode; use those rather than inferring mode from UI state.
import 'package:flutter/foundation.dart';
if (kDebugMode) {
print('Debug-only diagnostic');
}
Profile mode is the right place for many performance checks
Debug builds include assertions and development instrumentation that can distort timing. If the question is whether an animation janks or a scrolling screen meets performance expectations, profile mode is usually more representative than debug mode while still supporting performance tooling. Hiding the banner makes a debug demo look cleaner; it does not make that build a meaningful performance benchmark.
Keep debug visual flags out of committed release behavior
Flags such as paint-size overlays and repaint indicators are useful when diagnosing a layout or rendering problem, but they can make screenshots and tests confusing if left enabled globally. Gate temporary diagnostics behind debug-only code and remove them when the investigation is finished rather than treating all debug visuals as one switch controlled by debugShowCheckedModeBanner.