Advanced hot reload and hot restart functionality for Dart applications with true VM-based hot reload capabilities, similar to Flutter's development experience.
- π₯ True Hot Reload: Uses Dart VM service to reload code while preserving application state (like Flutter)
- π Hot Restart: Full process restart when hot reload isn't possible
- π Auto Mode: Intelligently tries hot reload first, falls back to restart
- β¨οΈ Flutter-like Commands: 'r' for hot reload, 'R' for hot restart, 'q' to quit
- π File Watching: Configurable paths and extensions with debouncing
- π― Smart Fallback: Graceful error handling with automatic mode switching
- π Multi-Service Support: Run multiple services simultaneously with coordinated reload
- π Real-Time Web Dashboard: Live monitoring, metrics, file watching, and reload history
- β‘ Advanced Pattern Matching: Glob patterns, regex, and predefined presets for sophisticated file filtering
dev_dependencies:
utopia_hotreload: ^1.0.0
import 'dart:io';
import 'package:utopia_hotreload/utopia_hotreload.dart';
void main() async {
await DeveloperTools.start(
script: () async {
// Your application code here
final server = await HttpServer.bind('127.0.0.1', 8080);
print('π Server running on http://127.0.0.1:8080');
await for (final request in server) {
request.response
..write('Hello from hot reload! Time: ${DateTime.now()}')
..close();
}
},
watchPaths: ['lib', 'bin'],
watchExtensions: ['.dart'],
);
}
The API is designed to be simple and Flutter-like:
import 'package:utopia_hotreload/utopia_hotreload.dart';
void main() async {
await DeveloperTools.start(
script: () async {
// Your application code here
},
);
}
import 'dart:io';
import 'package:utopia_http/utopia_http.dart';
import 'package:utopia_hotreload/utopia_hotreload.dart';
void main() async {
await DeveloperTools.start(
script: () async {
final app = Http(ShelfServer(InternetAddress.anyIPv4, 8080));
app.get('/').inject('response').action((Response response) {
response.text('Hello with hot reload! π₯');
return response;
});
await app.start();
},
watchPaths: ['lib', 'example'],
watchExtensions: ['.dart'],
);
}
await DeveloperTools.start(
script: () async {
// Your server code
},
watchPaths: ['lib', 'bin', 'web'],
watchExtensions: ['.dart', '.yaml'],
ignorePatterns: ['**/.dart_tool/**', '**/build/**'],
debounceDelay: Duration(milliseconds: 300),
verbose: true,
);
Enable the built-in web dashboard for real-time monitoring of your development session:
await DeveloperTools.start(
script: () async {
// Your application code
},
enableDashboard: true, // Enable the web dashboard
dashboardPort: 9000, // Dashboard port (defaults to 9000)
watchPaths: ['lib', 'bin'],
);
When enabled, the dashboard provides:
- π Real-time Metrics: Uptime, memory usage, reload statistics
- π File Monitoring: Live view of watched files and recent changes
- π Reload History: Timeline of hot reloads and restarts with performance data
- βοΈ Service Management: Start, stop, and restart services from the web interface
- π Performance Insights: Success rates, average reload times, and error tracking
Access the dashboard at: http://localhost:9000
(or your configured port)
Live Metrics Panel:
- Application uptime
- Memory usage tracking
- Reload success/failure rates
- Average reload times
File Watching Panel:
- Real-time list of watched files
- Recent file changes with timestamps
- File pattern matching status
Reload History:
- Complete timeline of reload events
- Performance metrics for each reload
- Error details and diagnostics
Service Management:
- View all running services
- Control individual services
- Real-time status updates
When you run your application, you'll see:
π₯ Hot reload enabled. Press:
r + Enter: Hot reload
R + Enter: Hot restart
q + Enter: Quit
π Starting application with auto hot reload...
π Watching paths: [lib, bin]
π Watching extensions: [.dart]
π‘ Commands available:
r + Enter: Hot reload (preserves state)
R + Enter: Hot restart (full restart)
q + Enter: Quit
π Server running on http://127.0.0.1:8080
r
+ Enter: Hot reload - Preserves application state, fasterR
+ Enter: Hot restart - Full application restart, more reliableq
+ Enter: Quit the development server
The package always uses auto mode (like Flutter), which:
- Tries hot reload first - Attempts to preserve state using Dart VM service
- Falls back to hot restart - If hot reload fails or isn't available
- Provides feedback - Shows which mode was used and why
- Uses Dart VM Service's
reloadSources()
API - Updates code in the running process - Preserves application state - Variables, connections, and server instances remain intact
- Same port, same PID - Server continues running without interruption
- Requires
--enable-vm-service
flag - Automatically enabled by the package - Similar to Flutter's hot reload - Instant code updates with state preservation
- Terminates and restarts the entire Dart process - Fresh compilation and clean state
- Loses all application state - Variables reset, connections closed, new server instance
- New port, new PID - Complete process restart
- More compatible across different scenarios - Guaranteed to pick up all code changes
- Used as fallback - When hot reload fails or for structural changes
The package intelligently chooses the best reload method:
π File changed: lib/server.dart
π₯ Performing true hot reload...
β
Hot reload completed - code updated in running process!
For structural changes that can't be hot reloaded:
π File changed: lib/server.dart
π₯ Performing true hot reload...
β Hot reload failed: Structural changes detected
π Hot reload not available, performing hot restart...
π Performing true hot restart (restarting entire process)...
β
Hot restart completed
Parameter | Type | Default | Description |
---|---|---|---|
script |
Function |
required | Your application entry point |
watchPaths |
List<String> |
['lib'] |
Directories to watch for changes |
watchExtensions |
List<String> |
['.dart'] |
File extensions to monitor |
ignorePatterns |
List<String> |
See below | Patterns to ignore |
debounceDelay |
Duration |
500ms |
Delay before triggering reload |
verbose |
bool |
false |
Enable detailed logging |
[
'.git/',
'.dart_tool/',
'build/',
'test/',
'.packages',
'pubspec.lock',
'.vscode/',
'.idea/',
'*.log',
'*.tmp',
]
The package includes a powerful real-time dashboard for monitoring your development environment when using multi-service mode.
- π΄ Live Service Monitoring: Real-time status of all running services
- π Performance Metrics: Memory usage, reload times, and success rates
- π Reload History: Detailed timeline of all hot reload and restart events
- β‘ Interactive Management: Start, stop, and restart services from the web interface
- π Analytics: Service performance breakdown and trends
- π Auto-Updates: WebSocket-based live updates every 2 seconds
The dashboard is automatically enabled for multi-service development:
import 'package:utopia_hotreload/utopia_hotreload.dart';
void main() async {
await DeveloperTools.startMultiple([
ServiceConfig(
name: 'api-server',
script: runApiServer,
displayName: 'API Server',
),
ServiceConfig(
name: 'web-server',
script: runWebServer,
displayName: 'Web Server',
),
],
enableDashboard: true, // Enable dashboard (default: true)
dashboardPort: 9000, // Dashboard port (default: 9000)
dashboardHost: 'localhost', // Dashboard host (default: 'localhost')
);
}
Once your multi-service environment starts, the dashboard will be available at:
π Dashboard available at: http://localhost:9000
- Uptime: Total development session time
- Active Services: Number of currently running services
- Total Reloads: Count of all reload operations performed
- Connected Clients: Number of dashboard connections
- Real-time Status: See which services are running, stopped, or failed
- Interactive Controls: Start, stop, and restart individual services
- Priority Display: View service startup priority and auto-start settings
- Configuration Info: Watch paths, environment variables, and settings
- Average Reload Time: Performance metrics for hot reload operations
- Memory Usage: Current memory consumption of the development process
- File Watches: Number of active file system monitors
- Success Rate: Percentage of successful vs failed reload attempts
- Recent Reload Events: Live feed of hot reload and restart operations
- Error Tracking: Detailed error messages when reloads fail
- Performance Trends: Visual indicators of reload performance over time
- Service-Specific History: Filter events by individual services
The dashboard also provides REST API endpoints for integration:
GET /api/status
- Basic dashboard statusGET /api/metrics
- Performance metricsGET /api/services
- Service list and statusGET /api/reload-history
- Reload event historyPOST /api/services/restart
- Restart a servicePOST /api/services/stop
- Stop a servicePOST /api/services/start
- Start a service
import 'dart:io';
import 'package:utopia_hotreload/utopia_hotreload.dart';
void main() async {
await DeveloperTools.startMultiple([
// API Server
ServiceConfig(
name: 'api',
script: () async {
final server = await HttpServer.bind('localhost', 3000);
await for (final request in server) {
request.response
..headers.contentType = ContentType.json
..write('{"message": "API is running", "time": "${DateTime.now()}"}')
..close();
}
},
displayName: 'API Server',
watchPaths: ['lib/api'],
priority: 10,
),
// Web Server
ServiceConfig(
name: 'web',
script: () async {
final server = await HttpServer.bind('localhost', 8080);
await for (final request in server) {
request.response
..headers.contentType = ContentType.html
..write('<h1>Web Server</h1><p>Dashboard: <a href="http://localhost:9000">View Dashboard</a></p>')
..close();
}
},
displayName: 'Web Server',
watchPaths: ['lib/web'],
priority: 5,
),
]);
}
import 'dart:io';
import 'package:utopia_hotreload/utopia_hotreload.dart';
void main() async {
await DeveloperTools.start(
script: () async {
final server = await HttpServer.bind('127.0.0.1', 8080);
await for (final request in server) {
request.response
..headers.contentType = ContentType.html
..write('''
<h1>Hot Reload Demo</h1>
<p>Time: ${DateTime.now()}</p>
<p>Try editing this file!</p>
''')
..close();
}
},
);
}
import 'dart:io';
import 'package:utopia_hotreload/utopia_hotreload.dart';
void main() async {
await DeveloperTools.start(
script: () async {
print('π Console app with hot reload');
print('Current time: ${DateTime.now()}');
// Keep running
await stdin.first;
},
verbose: true,
);
}
If you were using HttpDev
from utopia_http
:
import 'package:utopia_http/utopia_http.dart';
void main() async {
await HttpDev.start(
script: () => runServer(),
watchPaths: ['lib'],
);
}
import 'package:utopia_hotreload/utopia_hotreload.dart';
void main() async {
await DeveloperTools.start(
script: () => runServer(),
watchPaths: ['lib'],
);
}
- Dart SDK 2.17.0 or higher
- For hot reload: Dart VM service support (automatically enabled)
If hot reload consistently fails:
- Check for structural changes - Hot reload can't handle class/method signature changes
- Use hot restart - Press
R
+ Enter for structural changes - Enable verbose mode - Set
verbose: true
to see detailed error messages
- Check watch paths - Ensure your files are in the specified
watchPaths
- Check extensions - Make sure file extensions are in
watchExtensions
- Check ignore patterns - Verify files aren't excluded by
ignorePatterns
- Reduce watch scope - Watch only necessary directories
- Increase debounce delay - Set higher
debounceDelay
for slower systems - Add ignore patterns - Exclude large directories like
node_modules
The auto mode provides automatic fallback, but you can also handle specific scenarios:
await DeveloperTools.start(
script: () async {
try {
// Your application code
} catch (e) {
print('Application error: $e');
// Handle gracefully
}
},
verbose: true, // See detailed reload information
);
await DeveloperTools.start(
script: () => runServer(),
watchPaths: ['lib', 'web', 'config'],
watchExtensions: ['.dart', '.yaml', '.json'],
);
MIT License - see LICENSE file for details.