or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-daemon

Unix daemon creation library for Node.js processes

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/daemon@1.1.x

To install, run

npx @tessl/cli install tessl/npm-daemon@1.1.0

index.mddocs/

Daemon

Daemon 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.

Package Information

  • Package Name: daemon
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install daemon

Core Imports

const daemon = require("daemon");

For ES modules:

import daemon from "daemon";

Basic Usage

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);

Capabilities

Self-Daemonization

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"
});

Script Daemonization

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 exits

Cluster 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);

Types

/**
 * 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;
}

Implementation Notes

Process Forking Behavior

  • Self-daemonization: The daemon() function re-spawns the current script as a new process. The original process exits after spawning the daemon child.
  • Double execution: Code before daemon() runs twice - once in the original process and once in the daemon child.
  • Process identification: Daemon processes have the __daemon environment variable set to true.

Process Management

  • Detached processes: All daemon processes are spawned with detached: true, making them independent of the parent.
  • Process cleanup: The parent process calls child.unref() to allow it to exit without waiting for the child.
  • Signal handling: Daemon processes must handle their own signals and cleanup.

Output Handling

  • Default behavior: By default, daemon processes ignore stdin, stdout, and stderr ('ignore' option).
  • Output redirection: Use file descriptors or streams to capture daemon output to files.
  • Log rotation: Consider implementing log rotation for long-running daemons with file output.

Error Handling

The daemon library relies on Node.js's child_process.spawn() for process creation. Common errors include:

  • ENOENT: Script file not found or not executable
  • EACCES: Permission denied accessing script or working directory
  • EMFILE: Too many open files (system limit reached)

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);
});