Processes configuration
Running code outside the main process — a pre-built OS executable, or your own Node.js worker — under processes.externalCommands and processes.utilityProcesses in electron.config.ts. Both are inert (no-op) with no configured aliases, so leaving them empty is safe.
Mental model: externalCommands vs utilityProcesses
Both are alias → trusted-config allowlists — the renderer only ever names an alias, never a file path or an arbitrary command — but they run different kinds of code:
externalCommands.<alias>runs an external OS executable (ffmpeg,git, a compiled CLI tool, ...). Communication is stdin/stdout/stderr as text/bytes; it hastimeoutMsandmaxOutputBytesbecause the model is "run it, capture its output."utilityProcesses.<alias>runs your own Node.js code as a separate, Electron-managed process (Electron.utilityProcess.fork()) — the modern replacement for spawningnodeyourself viachild_process. Communication is structuredpostMessage/onMessage, like a Web Worker but on the Node.js side. Useful for offloading heavy or crash-prone work (big computations, image processing, native addon calls) so it can't freeze or take down the main process.
processes.externalCommands.<alias>
| Field | Purpose |
|---|---|
command |
Executable name or path. The renderer can only reference the alias, never choose the command itself. |
resolve |
'app' (default) resolves from the packaged app's bin directory (resources/app/bin). 'path' resolves through the host PATH (command must be a bare executable name). 'absolute' uses an absolute path. |
cwd |
Optional working directory. Relative paths resolve from the app base for resolve: 'app'. |
platforms |
Optional OS allowlist using Node.js process.platform values, e.g. ['win32']. |
allowedArgs |
Optional exact argument allowlist — every runtime arg must match one entry. |
timeoutMs |
Default 30000. 0 disables the timeout. Timed-out commands receive SIGTERM, then SIGKILL after a short grace period. |
maxOutputBytes |
Default 1048576. 0 disables result capture while still streaming output events. |
Renderer side: window.Electron.externalCommands.run(alias, options) / .start(alias, options) / .kill(id), plus .onOutput(callback) / .onExit(callback) — see Usage.
processes.utilityProcesses.<alias>
| Field | Purpose |
|---|---|
modulePath |
Path to the Node.js entry module, resolved against the packaged app's resources/app/ (mirrors externalCommands's resolve: 'app'). Ship it via extraResources in electron-builder.config.ts — see Deployment. |
args |
Extra argv entries passed to the module's process.argv. |
env |
Extra environment variables merged over the current process.env. |
Renderer side: window.Electron.utilityProcess.start(alias, args) / .postMessage(id, message) / .kill(id), plus .onMessage(callback) / .onExit(callback).
Example — offload a heavy computation to a worker
// electron.config.ts
processes: {
utilityProcesses: {
heavyMath: { modulePath: 'workers/heavy-math.js' },
},
},
// workers/heavy-math.js — plain Node.js, no @devioarts/electron import.
// Talks to the main process via Electron's own parentPort, not process.send().
process.parentPort.on('message', (event) => {
const { type, payload } = event.data;
if (type === 'sumOfSquares') {
let total = 0;
for (let i = 0; i < payload.n; i++) total += i * i;
process.parentPort.postMessage({ type: 'result', total });
}
});
// renderer
const { id } = await window.Electron.utilityProcess.start('heavyMath');
const unsubscribe = window.Electron.utilityProcess.onMessage(({ id: msgId, message }) => {
if (msgId !== id) return;
console.log('Result:', message.total);
unsubscribe();
});
await window.Electron.utilityProcess.postMessage(id, {
type: 'sumOfSquares',
payload: { n: 100_000_000 },
});
// later:
await window.Electron.utilityProcess.kill(id);
Next: App & lifecycle · Security · UI configuration