How Fluxer Handles Multi-Instance Scenarios and Prevents Multiple App Launches
Fluxer uses Electron's requestSingleInstanceLock() API to acquire an OS-level mutex at startup, immediately quitting duplicate processes while the primary instance listens for second-instance events to handle subsequent launch attempts.
Fluxer is an Electron-based desktop application that ensures only one process runs at any given time using a robust single-instance lock pattern. According to the fluxerapp/fluxer source code, the implementation prevents multiple app launches while enabling the running instance to receive command-line arguments and deep-link URLs from subsequent attempts.
The Core Single-Instance Lock Mechanism
Fluxer's entry point implements a three-stage locking strategy that guarantees singleton behavior across all platforms.
Requesting the Lock on Startup
In fluxer_desktop/src/main/index.tsx, the application attempts to acquire a single-instance lock immediately upon startup using Electron's built-in API:
const gotTheLock = app.requestSingleInstanceLock(); // line 81
This method creates a mutex at the operating system level. When the first instance launches, gotTheLock evaluates to true, granting exclusive ownership. Any subsequent launches receive false and trigger immediate termination.
Exiting Duplicate Processes
If the lock cannot be obtained, the process exits cleanly without creating any windows or registering handlers:
if (!gotTheLock) {
app.quit(); // lines 84-85
}
This ensures that only one main process remains active, preventing resource conflicts and window duplication.
Handling Second-Instance Events
When a user attempts to launch Fluxer while it is already running, the primary instance receives a second-instance event instead of spawning a new process. The main entry point wires this handler immediately after securing the lock:
app.on('second-instance', (_event, argv, _workingDirectory) => {
handleSecondInstance(argv); // lines 86-88
});
The argv parameter contains the command-line arguments from the duplicate launch attempt, allowing Fluxer to process deep links or file associations even when triggered from a second instance.
Deep Link Processing in the Primary Instance
The actual handling of secondary launch arguments resides in fluxer_desktop/src/main/DeepLinks.tsx. The handleSecondInstance function receives the argument array and coordinates the response:
// src/main/DeepLinks.tsx
export function handleSecondInstance(argv: string[]) {
// Focus the main window and process deep-link URLs or file paths
}
This architecture ensures that URLs opened via protocol handlers or files dragged onto the application icon are routed to the existing window rather than being lost when the duplicate process quits.
Key Implementation Files
The single-instance guarantee spans several modules in the fluxer_desktop package:
fluxer_desktop/src/main/index.tsx– Main entry point that acquires the single-instance lock and registers thesecond-instanceevent listener.fluxer_desktop/src/main/DeepLinks.tsx– ExportshandleSecondInstance()to process command-line arguments and deep-link URLs forwarded from duplicate launches.fluxer_desktop/src/main/Window.tsx– Manages window focus and visibility operations called by the second-instance handler.fluxer_desktop/src/main/IpcHandlers.tsx– Registers IPC channels that rely on the singleton instance assumption.
Reusable Implementation Pattern
You can adapt Fluxer's approach for any Electron application using this minimal implementation:
import { app } from 'electron';
const gotTheLock = app.requestSingleInstanceLock();
if (!gotTheLock) {
app.quit();
} else {
app.on('second-instance', (_event, argv) => {
console.log('Second launch with arguments:', argv);
// Bring window to front or process deep links here
});
app.whenReady().then(() => {
// Initialize main window and menus
});
}
Summary
Fluxer prevents multiple concurrent launches by implementing an OS-level single-instance lock:
- Requests a mutex at startup using
app.requestSingleInstanceLock()inindex.tsx. - Terminates duplicate processes immediately if the lock is unavailable.
- Forwards launch arguments to the primary instance via the
second-instanceevent andhandleSecondInstance()handler. - Processes deep links in the running instance without spawning additional windows.
Frequently Asked Questions
How does Fluxer prevent multiple windows from opening?
Fluxer calls app.requestSingleInstanceLock() at startup in fluxer_desktop/src/main/index.tsx. If another instance is running, gotTheLock returns false and the new process executes app.quit() before creating any windows, ensuring only one GUI instance exists.
What happens to command-line arguments when launching Fluxer twice?
When a second launch occurs, the primary instance receives a second-instance event containing the new command-line arguments. The handleSecondInstance(argv) function in DeepLinks.tsx processes these arguments, enabling the running app to open files or URLs passed by the duplicate attempt.
Is the single-instance lock OS-specific?
No. Electron's requestSingleInstanceLock() creates a cross-platform mutex that works on Windows, macOS, and Linux. The implementation in fluxer_desktop/src/main/index.tsx uses this standard Electron API, making the behavior consistent across all supported operating systems.
Where is the single-instance logic implemented in Fluxer?
The core logic resides in fluxer_desktop/src/main/index.tsx at lines 81-88, where the lock is requested and the second-instance handler is registered. Supporting functionality for argument processing lives in fluxer_desktop/src/main/DeepLinks.tsx.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →