Graceful shutdown signal handler utility for Node.js (ESM and CommonJS)
- Register handlers for process signals (e.g.,
SIGTERM,SIGINT,SIGHUP) - Register async shutdown hooks to run on signal or process exit
- Customizable logger and process object
- Simple API for both ESM and CommonJS
- TypeScript type definitions included
- Well-tested with Jest
npm install @eliware/signalsimport log from '@eliware/log';
import registerSignals from '@eliware/signals'; // Default export
// or: import { registerSignals } from '@eliware/signals';
const { shutdown, getShuttingDown } = registerSignals({ log });const log = require('@eliware/log');
const registerSignals = require('@eliware/signals'); // Default export
// or: const { registerSignals } = require('@eliware/signals');
const { shutdown, getShuttingDown } = registerSignals({ log });You can call registerSignals multiple times to add async shutdown hooks. All hooks will be run (in order of registration) when a signal is received or the process exits (via exit or beforeExit).
// Simulate a resource that needs cleanup (e.g., database connection)
const fakeDb = {
close: async () => {
return new Promise(resolve => setTimeout(() => {
log.info('Fake DB connection closed');
resolve();
}, 100));
}
};
// Register signal handlers
registerSignals({ log });
// Add shutdown hook for closing the fake DB connection
registerSignals({
log,
shutdownHook: async (signal) => {
await fakeDb.close();
log.info(`Cleanup complete on ${signal}`);
}
});Note: Both the default export and named export
registerSignalsare available in both ESM and CommonJS.
Registers shutdown handlers for the specified signals and allows registering async shutdown hooks.
processObj(default:process): The process object to attach handlers to.log(default:@eliware/log): Logger for output. Should havedebug,info,warn, anderrormethods.signals(default:[ 'SIGTERM', 'SIGINT', 'SIGHUP' ]): Array of signals to listen for.shutdownHook(optional): An async function to run during shutdown. You can callregisterSignalsmultiple times to add multiple hooks.
An object with:
shutdown(signal: string): Promise<void>— Manually trigger shutdown logic.getShuttingDown(): boolean— Returns whether shutdown is in progress.
Shutdown hooks will run on signal,
process.exit, orbeforeExit.
Type definitions are included:
import registerSignals, { RegisterSignalsOptions } from '@eliware/signals';
// Optionally provide options
const options: RegisterSignalsOptions = {
processObj: process, // optional, defaults to process
log: myLogger, // optional, defaults to @eliware/log
signals: ['SIGTERM', 'SIGINT', 'SIGHUP'], // optional, defaults as shown
shutdownHook: async (signal) => { /* ... */ } // optional
};
const { shutdown, getShuttingDown } = registerSignals(options);
// Types:
// interface RegisterSignalsOptions {
// processObj?: NodeJS.Process;
// log?: typeof log;
// signals?: string[];
// shutdownHook?: (signal: string) => Promise<void>;
// }
//
// function registerSignals(options?: RegisterSignalsOptions): {
// shutdown: (signal: string) => Promise<void>;
// getShuttingDown: () => boolean;
// };For help, questions, or to chat with the author and community, visit:


