Hot Reload — a technology that allows updating the code of a running mobile application without restarting and losing the current state. The developer changes the source code — within a second the changes appear on the device or emulator screen. This is a key feature of Flutter and React Native, radically speeding up development iterations: the edit-view cycle time is reduced from 5–10 seconds (rebuild) to 300–500 milliseconds. According to Flutter Documentation, 2025, hot reload performs incremental compilation of changed code and sends the update to Dart VM.
Key Takeaways
Hot Reload is a development mechanism where source code is modified and applied to an already running application without stopping it. The developer edits a file, saves it, and within 0.3–2 seconds the updated interface appears on the screen. The application state (counters, scroll position, entered data) is preserved — the developer does not lose context.
The concept of hot reload originated in early web tools (LiveReload, 2010) and was adapted for mobile development by Flutter (2017) and React Native (2015). Today, hot reload is a mandatory feature of modern mobile frameworks, alongside debug configuration and profiling. Without hot reload, UI development is considered inefficient: each change review requires 10–30 seconds for rebuild and launch.
Technically, hot reload consists of three steps: change detection (file watcher), compilation of changed code (incremental compiler), and application (hot patching). Each framework implements these steps differently, but the result is the same: minimal delay between edit and display.
Hot Reload in Flutter is built on the Dart VM architecture and JIT compilation. When the developer presses “Hot Reload” in the IDE or saves a file, Flutter performs incremental compilation of changed Dart libraries into kernel files (.dill). The Dart VM loads these files and replaces the implementations of changed functions in the running application.
// Flutter stateful widget with state preserved during hot reload
class CounterWidget extends StatefulWidget {
@override
State createState() => _CounterState();
}
class _CounterState extends State {
int _counter = 0;
@override
Widget build(BuildContext context) {
return Column(
children: [
Text('Counter: $_counter'),
ElevatedButton(
onPressed: () => setState(() => _counter++),
child: Text('Increment'),
),
],
);
}
}
In the example, the StatefulWidget CounterWidget preserves the _counter field during hot reload. The Dart VM recreates the state (State), calling reassemble(), but does not reset _counter — the value is preserved unless the widget is completely recreated. Flutter calls reassemble() for all State objects, and build() runs again with the updated code and preserved state.
When hot reload does not work: if a static initialization variable (static const), global variable, main(), enum/mixin class declaration, or code in @override initState() has changed. In these cases, Hot Restart is required. According to the Flutter Team (2025), hot reload is successful in 85–90% of cases; 10–15% of changes require a full restart.
Dart VM in debug mode operates as a JIT compiler: it interprets Dart code through kernel format (analogous to bytecode). Hot reload loads a new kernel file and replaces old function definitions. The VM does not restart isolates — all asynchronous operations (Future, Stream) continue running. In release mode, Dart is compiled AOT (dart2native), and hot reload is unavailable.
Fast Refresh (formerly Hot Reloading) in React Native uses Metro bundler — a JavaScript module bundler that monitors file changes. When the developer saves a file, Metro compiles only the changed module (HMR — Hot Module Replacement) and sends the update via WebSocket to the running application.
// React Native component with state preservation during hot reload
import React, { useState } from 'react';
import { View, Text, Button } from 'react-native';
const Counter = () => {
const [count, setCount] = useState(0);
return (
<View>
<Text>Counter: {count}Text>
<Button title="Increment"
onPress={() => setCount(c => c + 1)} />
View>
);
};
Fast Refresh preserves React state (useState, useReducer) when updating the module. Metro HMR transmits only the diff of the changed module — not the entire bundle. React Native uses React Fast Refresh, developed by the React team (Dan Abramov, 2019): it generates a new render for the component but preserves hook states and props if the component signature has not changed.
Fast Refresh does not work when changing: component export, hooks (useEffect, useMemo), module dependencies, and native modules (Java/Objective-C). Such changes require Reload (full JS bundle reload) or Rebuild (native code rebuild). Fast refresh time is 200–800 ms, full reload is 2–5 seconds.
Hot Reload and Hot Restart are two code update modes with different use cases. Hot Reload is suitable for UI changes (styles, layout, colors, texts), when class structure and state type do not change. Hot Restart is necessary when changing method signatures, adding new widgets/components to the root tree, modifying initState, and native modules.
| Characteristic | Hot Reload | Hot Restart |
|---|---|---|
| Speed | 0.3–2 seconds | 2–10 seconds |
| State preservation | Yes (variables, state, navigation stack) | No (application starts fresh) |
| Compilation | Incremental (changes only) | Full Dart/JS recompilation |
| When to use | UI tweaks, styles, texts, layout | Structural changes, new modules, native code |
| Flutter | Hot Reload (R) | Hot Restart (Shift + R) |
| React Native | Fast Refresh | Reload (Cmd + R) |
Recommended strategy: start with hot reload. If changes are not applied (IDE shows “Reload needed”) — perform hot restart. In Flutter, the button icon changes: lightning bolt (⚡) for hot reload, crossed-out lightning bolt if restart is required. Development efficiency with hot reload is 40–60% higher compared to full rebuilds (JetBrains Developer Survey 2024 data).
Code injection is the general mechanism of hot reload used by all frameworks. It includes three phases. First — change detection: a file watcher (built into the IDE) or file system (FSNotify) detects a change in .dart, .js, .tsx file. Second — compilation: the incremental compiler transforms only the changed file into an intermediate representation (kernel .dill for Dart, HMR-module for JS). Third — application: new code is sent to the device and replaces old definitions in the running application's memory.
Hot patching is a technique where the runtime replaces the function pointer in the virtual method table. Dart VM uses ClassTable — an internal structure containing all loaded classes. During hot reload, the VM finds the class in ClassTable and replaces its function definitions with new ones from the kernel file. All existing class instances automatically get the new behavior.
// Flutter: reassemble callback for managing state after hot reload
class MyWidget extends StatefulWidget {
@override
State createState() => _MyState();
}
mixin ReloadAware on State {
@override
void reassemble() {
super.reassemble();
// Reset cache or data after hot reload
clearCache();
}
}
In the example, the ReloadAware mixin overrides the reassemble() method, which the Dart VM calls on each State object after hot reload. The developer can reset the cache, reinitialize resources, or perform state migration. Without this method, old data may remain in the cache and cause inconsistencies after widget updates.
Hot patching does not work for changes requiring memory reallocation for new fields, changing variable type in a class, adding new fields to StatefulWidget, changing enum values or generic parameters. These changes are incompatible with existing objects in memory — the Dart VM cannot “shuffle” fields in already allocated objects. For such cases, hot restart or a full rebuild is required.
Native Android and iOS development traditionally lacks full hot reload. Android Studio with Android 11+ and AGP 4.2+ supports Apply Changes: code update without restarting the application. Apply Changes works through Android Runtime (ART) — it replaces method implementations in dex files on the fly. However, Apply Changes is limited: it does not work for resource changes (layout.xml, drawable), manifest, and native libraries.
Apple introduced Previews (SwiftUI Preview) in Xcode 15 (2023) — this is not hot reload in the classic sense. Previews compile the preview section separately from the main application and show the result in the Xcode canvas. When saving a file, the Preview updates in 1–3 seconds, but the application state is not preserved. For UIKit projects, hot reload is available through third-party tools: InjectionIII (John Holdsworth) and SwiftHotReload.
Kotlin Multiplatform (KMP) received experimental hot reload support from JetBrains starting in 2024. The mechanism is based on Kotlin/Native runtime with function replacement in the object file (.klib). JetBrains Compose Multiplayer uses its own hot reload implementation, similar to Flutter: incremental compilation and class replacement in Kotlin/Native runtime. Speed is 1–3 seconds, available only for UI changes.
Apply Changes is an Android Studio mechanism that uses the ART runtime API. When saving code, Android Studio determines which classes have changed and sends their dex files to the device via adb. ART replaces method implementations in the running application without stopping. Apply Changes works in three modes: Instant Run (fast method replacement), Swap (class replacement with instance recreation), and Restart Activity (if changes are incompatible with the current state).
Frequently Asked Questions
Hot Reload updates code without restarting the application and preserves state. Live Reload reloads the entire application or web page when files change. Live Reload is simpler to implement but slower and loses state. Flutter and React Native use hot reload; web tools use live reload.
Hot Reload does not work for changes requiring memory reallocation (new class fields), changes to static constants (static const), widget renaming, enum or generic parameter changes. These changes are incompatible with existing objects in Dart VM or JavaScript runtime memory.
Yes, hot reload works on both physical devices and emulators. Flutter sends kernel files to the device via USB (adb forward) or Wi-Fi. React Native uses WebSocket through the Metro bundler. The delay on a physical device is typically 10–30% higher than on an emulator.
Xcode Previews (since 2021) is an analog of hot reload for SwiftUI, but with limitations: previews are compiled separately, do not support app navigation and complex states. Apple does not provide an official hot reload for iOS. Third-party tools: InjectionIII and SwiftHotReload use Objective-C Runtime for code injection.
If the UI displays incorrectly after hot reload: perform a hot restart. If the issue is in the data — check the reassemble() callback in Flutter or useEffect cleanup in React Native. For persistent problems, use Flutter Clean or Reset Metro Cache. If a bug reproduces only after reload — it is a sign of incompatibility between changes and the existing state.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also