A robust Flutter plugin to ensure only one instance of your desktop application runs at a time. Supports Windows and macOS.
- Prevents duplicate application instances on Windows & macOS.
- Automatically focuses the original window when a duplicate is launched.
- Customizable alert messages with multi-language support.
- Flexible configuration for mutexes (Windows) and lockfiles (macOS).
- Special handling for debug mode to improve development workflow.
| Windows | macOS | Linux |
|---|---|---|
| ✅ | ✅ | 🚧 |
Add flutter_alone to your pubspec.yaml file:
dependencies:
flutter_alone: ^3.2.4Then, run flutter pub get.
For the plugin to work correctly, some platform-specific setup is required. Please follow the detailed instructions in our Platform Setup Guide.
This guide covers:
- Windows: Resolving conflicts when using the
window_managerpackage. - macOS: Handling app reactivation (e.g., clicking the dock icon). This is critical for system tray apps to ensure the window reappears correctly.
Import the package in your main.dart file and add the initialization logic before runApp.
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_alone/flutter_alone.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// Platform-specific configuration
FlutterAloneConfig? config;
if (Platform.isWindows) {
config = FlutterAloneConfig.forWindows(
windowsConfig: const DefaultWindowsMutexConfig(
packageId: 'com.example.myapp',
appName: 'My App',
),
messageConfig: const EnMessageConfig(),
);
} else if (Platform.isMacOS) {
config = FlutterAloneConfig.forMacOS(
macOSConfig: const MacOSConfig(
lockFileName: 'my_app.lock',
),
messageConfig: const EnMessageConfig(),
);
}
// Check for duplicate instance
if (config != null && !await FlutterAlone.instance.checkAndRun(config: config)) {
// Exit if another instance is running
exit(0);
}
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
void dispose() {
// IMPORTANT: Release resources on exit
FlutterAlone.instance.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: Scaffold(
body: Center(
child: Text('Hello, World!'),
),
),
);
}
}For more detailed options, such as custom mutexes, messages, and debug settings, please see our Advanced Configuration Guide.
A: It prevents the Windows FindWindow() API from failing. See the Platform Setup Guide for a full explanation.
A: No. The user only sees the final title set by window_manager.
A: You can ignore the window_manager setup guide.
Contributions are welcome! Please feel free to submit pull requests or create issues.