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.

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:

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() in index.tsx.
  • Terminates duplicate processes immediately if the lock is unavailable.
  • Forwards launch arguments to the primary instance via the second-instance event and handleSecondInstance() 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →