What is the difference between hot reload and hot restart?
2 min read
Flutter Tooling
Hot Reload (r) | Hot Restart (R) | |
|---|---|---|
| Injects new code | ✅ | ✅ |
| Restarts Dart VM | ❌ | ✅ |
| Preserves widget state | ✅ | ❌ |
Re-runs main() | ❌ | ✅ |
Re-runs initState() | ❌ | ✅ |
Re-runs build() | ✅ | ✅ |
| Typical speed | ~200ms | ~2–3s |
Behind the scenes: reload swaps class definitions while keeping object instances alive. Restart blows away the heap and starts fresh.
What each gets you
class _CounterState extends State<Counter> {
int _count = 5;
@override
Widget build(BuildContext context) =>
Text('Count: $_count', style: TextStyle(color: Colors.red));
}
// You change Colors.red → Colors.blue and press:
// • Hot reload → text turns blue, _count still 5
// • Hot restart → text turns blue, _count back to 0
When you need a hot restart instead
| Change | Why reload can't handle it |
|---|---|
Field default values / initState logic | reload doesn't re-run initState |
| Global / top-level variable initialisers | already evaluated, won't re-run |
| Enum changes (added/renamed values) | enum identity captured by existing objects |
| Generic type changes | type parameters baked into existing instances |
Adding const to a constructor that wasn't | canonicalisation cache stale |
| Native code (iOS/Android, plugins) | reload is Dart-only |
Changes to main() itself | only re-run on restart |
If you see a "Some changes won't take effect" warning, that's Flutter telling you a restart is needed.
When to reach for which
| Situation | Use |
|---|---|
| Tweaking colors, paddings, copy, layout | Hot reload |
| Changing build() logic for current screen | Hot reload |
Updating an initState body, default field value | Hot restart |
| Modifying an enum or generic class | Hot restart |
| Updating a plugin / native code | Stop and full restart (sometimes rebuild) |
| App in a weird state you want to reset | Hot restart |
Common mistakes to avoid
// ❌ "Hot reload didn't pick up my fix" — when you changed initState
@override
void initState() {
super.initState();
_loadConfig(); // edited this body → reload won't re-run it
}
// ✅ Hot restart, or temporarily call it from build() while iterating
// ❌ Confusing UI not updating with broken code
// Check the terminal — reload prints "1 Reloaded" or warnings
// If you don't see your widget update, something didn't apply.
// ❌ Hot reloading after upgrading flutter / dart SDK
// Always do a full restart (and sometimes `flutter clean`) after SDK changes
// ❌ Expecting reload to clear caches or rerun network calls
// Anything inside a one-time future / stream stays as-is until restart
Interview follow-ups
-
Why does hot reload preserve state but hot restart doesn't? Reload patches class definitions in the running VM — existing objects keep their fields and identities, but next call to a method uses the new code. Restart blows away the isolate's heap and re-runs
main(), so every object is newly constructed. -
Why doesn't hot reload re-run
initStateormain? Because those are one-time setup. Reload assumes objects are still valid — it just refreshes their behaviour. Re-running setup would defeat the "preserve state" goal. -
Why do enum changes require a restart? Enum values are canonical instances baked into existing objects. Changing the enum could leave objects holding stale references that no longer match the new definition. Restart guarantees consistency.
-
What's the difference between hot restart and a full app restart? Hot restart restarts the Dart VM only — keeping the embedder, native plugins, and engine warm. A full restart (stop and re-run) rebuilds native code too — needed when you touch iOS/Android sources or update Flutter itself.
How helpful was this content?
Please sign in to rate this article.