ComfyUI-Manager can restart ComfyUI after installing custom node packs. This document describes how the launcher handles that.
ComfyUI-Manager's restart logic (rebootAPI() in js/common.js) has three code paths:
-
electronAPIpresent — callswindow.electronAPI.restartApp()immediately, bypassing the user confirmation dialog. The Electron host is responsible for restarting the process. -
__COMFY_CLI_SESSION__env var set — the/manager/rebootendpoint (after user confirmation) creates a marker file at$__COMFY_CLI_SESSION__.reboot, then callsexit(0). The launcher detects the marker and respawns. -
Neither present (legacy) — calls
os.execv()to replace the current process in-place. This creates an orphaned process that the launcher cannot track. This path must be avoided.
When spawning ComfyUI, lib/ipc.js sets __COMFY_CLI_SESSION__ in the child process environment, pointing to a unique temp path. This ensures Manager never falls through to the os.execv() legacy path.
We deliberately do not inject window.electronAPI into the ComfyUI BrowserWindow. If we did, Manager would skip its confirmation dialog and call restartApp() immediately with no user feedback. Instead, we let Manager use its normal server-side /manager/reboot flow:
- User clicks Restart → Manager shows its confirmation dialog
- User confirms → Manager calls
/manager/reboot - Server creates
.rebootmarker file and callsexit(0) - Our exit handler detects the marker and respawns
This preserves Manager's own UX while the launcher handles the process lifecycle correctly.
attachExitHandler in lib/ipc.js runs on every process exit:
- Checks for the
.rebootmarker file at the session path - If found: deletes the marker, respawns ComfyUI with the same command/args/env, reattaches stdout/stderr forwarding, updates
_runningProc, and callsonComfyRestartedwith the new process handle - If not found: declares the process stopped (
comfy-exited)
In app window mode, onComfyRestarted in main.js polls waitForPort until the new server is ready, then reloads the ComfyUI BrowserWindow URL. The window stays open throughout.
In console mode, the restart message ("--- ComfyUI restarting ---") is written to the terminal via sendOutput (the same comfy-output channel as stdout/stderr), so it appears inline in the console view.
stopRunning() in lib/ipc.js handles both cases — if a tracked process exists, it uses killProcessTree; it also calls killByPort to catch any process listening on the port. The running state is cleared so the exit handler does not respawn.
- ComfyUI-Manager restart logic:
ltdrdata/ComfyUI-Manager→js/common.js(rebootAPI),glob/manager_server.py(/manager/reboot) - Comfy-Org/desktop approach: injects
electronAPIand usesRESTART_COREIPC channel. We chose not to follow this pattern to preserve Manager's confirmation dialog.