# exit-hook

> Run some code when the process exits

Latest version **5.1.0** (published 2026-02-04) · MIT license · 0 weekly downloads

## Install

```sh
npm install exit-hook
pnpm add exit-hook
yarn add exit-hook
bun add exit-hook
```

## Health

**Score 60/100 (C)** — status: stable.

Positive: has types; esm support; no vulnerabilities; high quality score.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 5.1.0 |
| Published | 2026-02-04 |
| First published | 2014-08-31 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM |
| Node | >=20 |
| Dependencies | 0 |
| Unpacked size | 12.9 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 301 |
| Author | Sindre Sorhus |
| Maintainers | sindresorhus |
| Keywords | exit, quit, process, hook, graceful, handler, shutdown, sigterm, sigint, terminate, kill, stop, event, signal, async, asynchronous |

## Links

- npm: https://www.npmjs.com/package/exit-hook
- Repository: https://github.com/sindresorhus/exit-hook
- Homepage: https://github.com/sindresorhus/exit-hook#readme
- Issues: https://github.com/sindresorhus/exit-hook/issues
- Funding: https://github.com/sponsors/sindresorhus
- npm.io page: https://npm.io/package/exit-hook

## Alternatives

- [async-exit-hook](https://npm.io/package/async-exit-hook.md) — 3.7M weekly downloads
- [evnty](https://npm.io/package/evnty.md) — 7.2K weekly downloads
- [eleventy-plugin-asciidoc](https://npm.io/package/eleventy-plugin-asciidoc.md) — 3.5K weekly downloads
- [@jswork/next-get2get](https://npm.io/package/@jswork/next-get2get.md) — 945 weekly downloads
- [@dashersw/axon](https://npm.io/package/@dashersw/axon.md) — 934 weekly downloads

## Recent versions

- 5.1.0 (latest) — 2026-02-04
- 5.0.1 — 2025-11-19
- 5.0.0 — 2025-10-13
- 4.0.0 — 2023-08-31
- 3.2.0 — 2023-01-20
- 3.1.4 — 2022-12-09
- 3.1.3 — 2022-12-08
- 3.1.2 — 2022-10-22
- 3.1.1 — 2022-10-16
- 3.1.0 — 2022-08-23
- 3.0.0 — 2021-08-27
- 2.2.1 — 2021-02-27
- 2.2.0 — 2019-04-16
- 2.1.0 — 2019-04-09
- 2.0.0 — 2018-03-24
- … 3 more at https://npm.io/package/exit-hook/versions

## README

# exit-hook

> Run some code when the process exits

The `process.on('exit')` event doesn't catch all the ways a process can exit.

This package is useful for cleaning up before exiting.

## Install

```sh
npm install exit-hook
```

## Usage

```js
import exitHook from 'exit-hook';

exitHook(signal => {
	console.log(`Exiting with signal: ${signal}`);
});

// You can add multiple hooks, even across files
exitHook(() => {
	console.log('Exiting 2');
});

throw new Error('🦄');

//=> 'Exiting'
//=> 'Exiting 2'
```

Removing an exit hook:

```js
import exitHook from 'exit-hook';

const unsubscribe = exitHook(() => {});

unsubscribe();
```

## API

### exitHook(onExit)

Register a function to run during `process.exit`.

Returns a function that removes the hook when called.

#### onExit

Type: `(signal: number) => void`

The callback function to execute when the process exits.

### asyncExitHook(onExit, options)

Register a function to run during `gracefulExit`.

Returns a function that removes the hook when called.

Please see [Async Notes](#asynchronous-exit-notes) for considerations when using the asynchronous API.

#### onExit

Type: `(signal: number) => (void | Promise<void>)`

The callback function to execute when the process exits via `gracefulExit`, and will be wrapped in `Promise.resolve`.

#### options

Type: `object`

##### wait

Type: `number`

The amount of time in milliseconds that the `onExit` function is expected to take. When multiple async handlers are registered, the longest `wait` time will be used.

```js
import {asyncExitHook} from 'exit-hook';

asyncExitHook(async () => {
	console.log('Exiting');
}, {
	wait: 300
});

throw new Error('🦄');

//=> 'Exiting'
```

Removing an asynchronous exit hook:

```js
import {asyncExitHook} from 'exit-hook';

const unsubscribe = asyncExitHook(async () => {
	console.log('Exiting');
}, {
	wait: 300
});

unsubscribe();
```

### gracefulExit(signal?: number): void

Exit the process and make a best-effort to complete all asynchronous hooks.

If you are using `asyncExitHook`, consider using `gracefulExit()` instead of `process.exit()` to ensure all asynchronous tasks are given an opportunity to run.

```js
import {gracefulExit} from 'exit-hook';

gracefulExit();
```

#### signal

Type: `number`

The exit code to use. Same as the argument to `process.exit()`.

If not specified, the process will exit with `process.exitCode` if set, otherwise `0`.

## FAQ

### Why don't my exit hooks run when using nodemon?

By default, nodemon uses `SIGUSR2` to restart your app. Since `SIGUSR2` is a user-defined signal, exit-hook does not handle it to avoid conflicts with your app logic.

Solution: Configure nodemon to use standard termination signals:

```sh
nodemon --signal SIGTERM your-app.js
```

Or in your `nodemon.json`:

```json
{
	"signal": "SIGTERM"
}
```

Alternatively, you can handle `SIGUSR2` in your app if you specifically need nodemon's default behavior:

```js
// Handle nodemon restart signal
process.on('SIGUSR2', () => {
	gracefulExit();
});
```

## Asynchronous Exit Notes

**tl;dr** If you have 100% control over how your process terminates, then you can swap `exitHook` and `process.exit` for `asyncExitHook` and `gracefulExit` respectively. Otherwise, keep reading to understand important tradeoffs if you're using `asyncExitHook`.

Node.js does not offer an asynchronous shutdown API by default [#1](https://github.com/nodejs/node/discussions/29480#discussioncomment-99213) [#2](https://github.com/nodejs/node/discussions/29480#discussioncomment-99217), so `asyncExitHook` and `gracefulExit` will make a "best effort" attempt to shut down the process and run your asynchronous tasks.

If you have asynchronous hooks registered and your Node.js process is terminated in a synchronous manner, a `SYNCHRONOUS TERMINATION NOTICE` error will be logged to the console. To avoid this, ensure you're only exiting via `gracefulExit` or that an upstream process manager is sending a `SIGINT` or `SIGTERM` signal to Node.js.

Asynchronous hooks should make a "best effort" to perform their tasks within the `wait` time, but also be written to assume they may not complete their tasks before termination.

---
_Source: https://npm.io/package/exit-hook · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
