Exiting Node.js when programmatically using "Concurrently" to run multiple scripts
Tags: node, javascript, tooling
Published: 2020-07-26 22:29:20

---
title: Exiting Node.js when programmatically using "Concurrently" to run multiple scripts
published: true
description: What to do when you exit Concurrently but your Node script is still running.
tags: Nodejs, JavaScript, Tooling
---
[Concurrently](https://github.com/kimmobrunfeldt/concurrently) is a Node package that allows you to run multiple scripts at the same time in Node.js. It's especially useful if you want to run your app's front-end and back-end from a single NPM command. 

Concurrently also has a Node API to start concurrent processes programmatically from within a script file. However, if you use concurrently programmatically, it may be unclear how to make sure everything shuts down cleanly when you kill the process in your command line.

Here's an example of what programmatic usage of Concurrently may look like:

```js
// package.json
{
  // ...other config properties
  "scripts": {
    "start": "node bootstrap.js",
  },
}
```

```js
// bootstrap.js
const concurrently = require('concurrently');

concurrently([
  "node back-end/server.js",
  "react-scripts start"
], {
  prefix: 'name',
  killOthers: ['failure', 'success'],
  restartTries: 3,
});
```

The `killOthers` property will ensure that all of Concurrently's processes shut down when one of them shuts down, but there's a problem. When you exit this script from the command line, you only exit Concurrently's processes: the calling script's process doesn't exit. This can cause some unexpected and undesirable behavior.

Thankfully, if you want the parent process to terminate when you exit Concurrently's processes, it's only a few extra lines of code.

```js
// bootstrap.js
const concurrently = require('concurrently');

concurrently([
  "node back-end/server.js",
  "react-scripts start"
], {
  prefix: 'name',
  killOthers: ['failure', 'success'],
  restartTries: 3,
}).then(
    function onSuccess(exitInfo) {
      // This code is necessary to make sure the parent terminates 
      // when the application is closed successfully.
      process.exit();
    },
    function onFailure(exitInfo) {
      // This code is necessary to make sure the parent terminates 
      // when the application is closed because of a failure.
      process.exit();
    }
  );
```

When Concurrently's processes terminate, Concurrently calls its `then(success, failure)` method. The `success` and `failure` parameters accept a function that fires after Concurrently's processes terminate, either through a success or failure. 

In my code example above, I've named these `onSuccess()` and `onFailure()` to help me remember which is which, but you could call these anything, or leave them nameless anonymous functions. Both receive an argument with information about each command that has been run. [You can read more about these arguments in the docs](https://github.com/kimmobrunfeldt/concurrently#programmatic-usage).

Inside my `onSuccess()` and `onFailure()` functions, I'm calling `process.exit()`, which exits the main node process. Now, when I exit the processes from my command line, it exits Concurrently's scripts **and** the Node script that called it.

By calling Concurrently programmatically in a Node script, you can keep your `package.json` file more manageable and add additional logic to how Concurrently behaves. 

Let me know if you found this post helpful!