Closing an Electron window does not have to quit the application. In Notifio, closing the control panel leaves its background polling running, so the app deliberately gives Electron’s window-all-closed event an empty handler. That is an application design choice—not a special Electron mode.
What an empty window-all-closed handler means
Electron emits window-all-closed after all application windows have closed. If an app subscribes to that event but does nothing in its callback, the callback itself does not call app.quit(); closing the final window therefore does not trigger a quit through that handler. The event is a place where an app can choose its policy, not an instruction that Electron must terminate the process. See the Electron app API.
As an Amazon Associate I earn from qualifying purchases.
That does not, by itself, explain every route through the app’s lifecycle. Electron documents that pressing Cmd+Q or calling app.quit() does not emit window-all-closed. A call to app.quit() begins the quit lifecycle with before-quit; if windows close successfully, Electron then terminates the app by default. will-quit is emitted later in that process. These are separate lifecycle signals, so an empty window-close callback does not prevent an explicit quit.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Why Notifio keeps running after its control panel closes
Notifio’s author, Daniel Pertu, describes the window as secondary to the work: “The window is the app, by default, and for us the window is the least important part of the app: it is a control panel for a poll loop that should still be running when nobody is looking at it.” The poll loop drives a browser, and the described implementation closes browser contexts on system suspend and before quitting. Those are choices in this app, not a general Electron requirement. The implementation is described in Pertu’s article on DEV Community.
#1 Best Overall
To make a window close different from an app exit, Notifio’s close handler hides the window unless a quitting flag has been set. A tray menu offers “Show Window” to reopen the control panel and “Quit” to exit. Choosing Quit sets the flag and calls app.quit(); the app also sets the flag on before-quit. That flag lets the close handler distinguish an ordinary close—which should hide the window—from closing windows as part of a real quit.
How the usual behavior differs by platform
Electron’s first-app tutorial describes common conventions, while leaving each app to implement its own behavior. Windows and Linux apps generally quit after all windows close. macOS apps generally continue running without open windows, and commonly recreate a window when the app is activated. The tutorial demonstrates the Windows/Linux convention by calling app.quit() when process.platform !== 'darwin', and recommends handling activate to reopen a window on macOS. Electron does not force every app to follow these conventions.
Rank #2
| Lifecycle choice | When the last window closes | How a user gets back in or quits |
|---|---|---|
| Common Windows/Linux convention | The app calls app.quit() from window-all-closed. |
Start the app again after it exits; a separate tray or other control can provide an explicit quit action if the app is designed to stay running. |
| Common macOS convention | The app remains active without windows. | Handle activate to create a window when none are open; use the app’s normal quit action to exit. |
| Notifio’s background-work choice | The empty handler does not quit, allowing the polling work to continue. | Use the tray’s “Show Window” item to reopen the control panel or “Quit” to stop the app. |
Electron documents the platform conventions in Building your First App. A useful way to choose a policy is to ask whether work must continue after the interface disappears, how users will discover and restore the hidden app, and what explicit action reliably exits it.
Recommended Free Tools
How to choose a close-versus-quit policy
- Quit on last-window close: Use this when closing the interface should end the app’s work. A common implementation is to call
app.quit()fromwindow-all-closedon Windows and Linux. - Keep working in the background: Leave the final-window event from quitting the app when background work must continue. Provide a clear way to reopen the interface and a distinct, discoverable quit command, such as a tray menu.
- Follow the macOS convention: Keep the app active without windows and handle
activateso users can open a window again. Do not assume that macOS behavior is automatic; implement it in the app.
Whichever policy you choose, ensure an explicit quit path calls app.quit() and that close-handling logic does not mistake the resulting window closures for a request to hide. For background work involving resources such as browser contexts, decide separately how those resources should be closed on suspend and on app exit; Notifio’s approach is one implementation, not a universal pattern.
Quick Recap
Best Value
Rank #4
Rank #3
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




