Unix daemon creation library for Node.js processes
npx @tessl/cli install tessl/npm-daemon@1.1.0Daemon is a Node.js library that provides simple and reliable Unix daemon creation capabilities. The library allows you to transform a running Node.js process into a daemon process by forking and detaching from the parent process, or spawn any script as a daemon with configurable options.
npm install daemonconst daemon = require("daemon");For ES modules:
import daemon from "daemon";const daemon = require("daemon");
// Turn current process into a daemon
console.log("Before daemon:", process.pid);
daemon();
console.log("After daemon:", process.pid); // Different PID in daemon process
// Spawn another script as a daemon
const child = daemon.daemon("./worker.js", ["arg1", "arg2"], {
stdout: process.stdout,
stderr: process.stderr
});
console.log("Daemon child PID:", child.pid);Transform the current Node.js process into a daemon by re-spawning as a detached background process.
/**
* Transform current process into daemon by re-spawning as detached process
* @param {Object} [opt] - Configuration options
* @param {Object} [opt.env] - Environment variables for daemon process (default: process.env)
* @param {string|Stream} [opt.stdout] - File descriptor or stream for stdout (default: 'ignore')
* @param {string|Stream} [opt.stderr] - File descriptor or stream for stderr (default: 'ignore')
* @param {string} [opt.cwd] - Current working directory for daemon (default: process.cwd())
* @returns {number|void} - Process PID if already daemon, exits parent process otherwise
*/
function daemon(opt)Usage Example:
const daemon = require("daemon");
// Basic daemonization
daemon();
// Daemonization with output redirection
daemon({
stdout: require("fs").openSync("/var/log/myapp.log", "a"),
stderr: require("fs").openSync("/var/log/myapp-error.log", "a")
});
// Daemonization with custom environment
daemon({
env: { ...process.env, NODE_ENV: "production" },
cwd: "/var/lib/myapp"
});Spawn any Node.js script as a daemon process with full configuration control.
/**
* Spawn a script as daemon process with configurable options
* @param {string} script - Path to the script to run as daemon
* @param {Array} args - Arguments to pass to the script
* @param {Object} [opt] - Configuration options
* @param {string|Stream} [opt.stdout] - File descriptor or stream for stdout (default: 'ignore')
* @param {string|Stream} [opt.stderr] - File descriptor or stream for stderr (default: 'ignore')
* @param {Object} [opt.env] - Environment variables for daemon process (default: process.env)
* @param {string} [opt.cwd] - Current working directory for daemon (default: process.cwd())
* @returns {ChildProcess} - Node.js ChildProcess object representing the daemon
*/
daemon.daemon = function(script, args, opt)Usage Examples:
const daemon = require("daemon");
const fs = require("fs");
// Basic script daemonization
const child = daemon.daemon("./worker.js", ["--port", "3000"]);
console.log("Daemon started with PID:", child.pid);
// Script daemonization with output capture
const child2 = daemon.daemon("./server.js", [], {
stdout: fs.openSync("/var/log/server.log", "a"),
stderr: fs.openSync("/var/log/server-error.log", "a"),
env: { ...process.env, PORT: "8080" },
cwd: "/opt/myapp"
});
// The child process is detached and will continue running
// even after the parent process exitsCluster Integration Example:
const daemon = require("daemon");
const cluster = require("cluster");
const numCPUs = require("os").cpus().length;
if (cluster.isMaster) {
// Set up cluster workers
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker) => {
console.log(`Worker ${worker.process.pid} died`);
cluster.fork(); // Restart worker
});
// Daemonize after cluster setup
return daemon();
}
// Worker process code
const http = require("http");
http.createServer((req, res) => {
res.writeHead(200);
res.end(`Process: ${process.pid}`);
}).listen(8000);/**
* Configuration options for daemon processes
*/
interface DaemonOptions {
/** File descriptor or stream for stdout output (default: 'ignore') */
stdout?: string | Stream;
/** File descriptor or stream for stderr output (default: 'ignore') */
stderr?: string | Stream;
/** Environment variables for daemon process (default: process.env) */
env?: Object;
/** Current working directory for daemon (default: process.cwd()) */
cwd?: string;
}
/**
* Node.js ChildProcess object returned by daemon.daemon()
* For complete interface, see Node.js child_process documentation
*/
interface ChildProcess {
/** Process ID of the daemon child */
pid: number;
/** Disconnect from the child process IPC channel */
unref(): void;
/** Event listeners for process lifecycle events */
on(event: 'error' | 'exit' | 'close', callback: Function): ChildProcess;
/** Kill the child process with optional signal */
kill(signal?: string): boolean;
}daemon() function re-spawns the current script as a new process. The original process exits after spawning the daemon child.daemon() runs twice - once in the original process and once in the daemon child.__daemon environment variable set to true.detached: true, making them independent of the parent.child.unref() to allow it to exit without waiting for the child.'ignore' option).The daemon library relies on Node.js's child_process.spawn() for process creation. Common errors include:
Error handling should be implemented around the child_process events:
const child = daemon.daemon("./worker.js", []);
child.on('error', (err) => {
console.error('Failed to start daemon:', err);
});
child.on('exit', (code, signal) => {
console.log('Daemon exited with code:', code, 'signal:', signal);
});