concurrently vs npm-run-all vs npm-run vs parallelshell
NPM Task Runner Libraries Comparison
1 Year
concurrentlynpm-run-allnpm-runparallelshellSimilar Packages:
What's NPM Task Runner Libraries?

NPM task runner libraries are tools that help developers execute multiple commands or scripts concurrently or sequentially in a Node.js environment. They streamline the development workflow by allowing developers to run scripts in parallel, manage dependencies, and automate repetitive tasks, thus enhancing productivity and efficiency. These libraries are particularly useful in modern web development, where multiple processes (like building, testing, and serving) often need to run simultaneously to optimize the development experience.

npm Package Downloads Trend
Github Stars Ranking
Stat Detail
Package
Downloads
Stars
Size
Issues
Publish
License
concurrently6,601,3487,239406 kB69a month agoMIT
npm-run-all3,259,7885,775-1076 years agoMIT
npm-run55,881186-77 years agoMIT
parallelshell6,925501-207 years agoMIT
Feature Comparison: concurrently vs npm-run-all vs npm-run vs parallelshell

Execution Model

  • concurrently:

    Concurrently allows you to run multiple commands in parallel, providing a simple syntax to execute scripts simultaneously. It handles the output of each command, displaying them in a single terminal window, which is useful for monitoring multiple processes at once.

  • npm-run-all:

    npm-run-all supports both parallel and sequential execution of npm scripts, allowing you to specify the order of execution. This flexibility is beneficial for complex workflows where certain scripts depend on the completion of others.

  • npm-run:

    npm-run executes npm scripts in a controlled environment, allowing for the management of environment variables and script parameters. It is designed to run scripts defined in the package.json file, ensuring that the execution context is consistent with npm's environment.

  • parallelshell:

    Parallelshell runs multiple shell commands in parallel, displaying their outputs in real-time. It is particularly useful for developers who want to monitor the output of various processes without switching between terminal tabs.

Ease of Use

  • concurrently:

    Concurrently is designed for simplicity and ease of use, requiring minimal configuration. You can quickly set it up in your project and start running commands without extensive documentation or learning curves.

  • npm-run-all:

    npm-run-all provides a clear command-line interface for managing script execution, making it easy to understand and use. Its documentation is straightforward, making it accessible for developers of all skill levels.

  • npm-run:

    npm-run offers a straightforward interface for running npm scripts, but it may require some understanding of npm's script management. It is user-friendly for those familiar with npm but may have a slight learning curve for newcomers.

  • parallelshell:

    Parallelshell is very easy to use, with a simple command structure that allows you to run multiple shell commands without complex setup. It is particularly appealing for users who prefer a no-frills approach.

Output Management

  • concurrently:

    Concurrently merges the output of all commands into a single terminal window, allowing for easy monitoring of multiple processes. It prefixes each output line with the command name, helping to distinguish between different processes.

  • npm-run-all:

    npm-run-all does not merge output in real-time but allows for organized output based on the execution order of scripts. This can be useful for debugging complex workflows where the order of execution matters.

  • npm-run:

    npm-run captures the output of npm scripts and can redirect it as needed. However, it does not provide real-time output merging like concurrently, which may be a consideration for developers needing immediate feedback.

  • parallelshell:

    Parallelshell displays the output of each command in real-time, making it easy to monitor multiple processes simultaneously. This feature is particularly useful for developers who need to keep track of various outputs without losing context.

Configuration Flexibility

  • concurrently:

    Concurrently requires minimal configuration, making it ideal for quick setups. You can easily add it to your npm scripts without extensive changes to your project structure.

  • npm-run-all:

    npm-run-all offers extensive configuration options, allowing you to specify execution order and conditions for running scripts. This makes it suitable for complex build processes where control over execution flow is critical.

  • npm-run:

    npm-run allows for some customization through environment variables and script parameters, providing flexibility for specific project needs. However, it is more focused on npm script execution than general command management.

  • parallelshell:

    Parallelshell is straightforward with limited configuration options, focusing on running commands in parallel without additional complexity. It is best for users who prefer simplicity over extensive configuration.

Community and Support

  • concurrently:

    Concurrently has a strong community and is widely used in the industry, ensuring good support and frequent updates. Its popularity means that many developers are familiar with it, making it easier to find help and resources.

  • npm-run-all:

    npm-run-all is also well-supported within the npm community, with good documentation and examples available. Its flexibility makes it a popular choice among developers managing complex scripts.

  • npm-run:

    npm-run is part of the npm ecosystem and benefits from the extensive documentation and community support associated with npm. However, it may not be as widely adopted as some other options.

  • parallelshell:

    Parallelshell has a smaller community compared to others, which may result in less frequent updates and support. However, it remains a useful tool for specific use cases.

How to Choose: concurrently vs npm-run-all vs npm-run vs parallelshell
  • concurrently:

    Choose concurrently if you need a simple solution to run multiple commands in parallel without complex configuration. It is lightweight and easy to use, making it ideal for straightforward tasks.

  • npm-run-all:

    Opt for npm-run-all if you want to run multiple npm scripts sequentially or in parallel with a single command. It offers flexibility in script execution order and is great for managing complex build processes.

  • npm-run:

    Select npm-run if you are looking for a way to run npm scripts with additional features like environment variable management and script execution in a more controlled manner. It is useful for projects that require specific environment setups.

  • parallelshell:

    Use parallelshell if you need a straightforward way to run multiple shell commands in parallel while keeping their outputs visible in the terminal. It is particularly useful for monitoring multiple processes at once.

README for concurrently

concurrently

Latest Release License Weekly Downloads on NPM CI Status Coverage Status

Run multiple commands concurrently. Like npm run watch-js & npm run watch-less but better.

Demo

Table of Contents

Why

I like task automation with npm but the usual way to run multiple commands concurrently is npm run watch-js & npm run watch-css. That's fine but it's hard to keep on track of different outputs. Also if one process fails, others still keep running and you won't even notice the difference.

Another option would be to just run all commands in separate terminals. I got tired of opening terminals and made concurrently.

Features:

  • Cross platform (including Windows)
  • Output is easy to follow with prefixes
  • With --kill-others switch, all commands are killed if one dies

Installation

concurrently can be installed in the global scope (if you'd like to have it available and use it on the whole system) or locally for a specific package (for example if you'd like to use it in the scripts section of your package):

| | npm | Yarn | pnpm | Bun | | ----------- | ----------------------- | ------------------------------ | -------------------------- | ------------------------- | | Global | npm i -g concurrently | yarn global add concurrently | pnpm add -g concurrently | bun add -g concurrently | | Local* | npm i -D concurrently | yarn add -D concurrently | pnpm add -D concurrently | bun add -d concurrently |

* It's recommended to add concurrently to devDependencies as it's usually used for developing purposes. Please adjust the command if this doesn't apply in your case.

Usage

Note The concurrently command is also available under the shorthand alias conc.

The tool is written in Node.js, but you can use it to run any commands.

Remember to surround separate commands with quotes:

concurrently "command1 arg" "command2 arg"

Otherwise concurrently would try to run 4 separate commands: command1, arg, command2, arg.

In package.json, escape quotes:

"start": "concurrently \"command1 arg\" \"command2 arg\""

You can always check concurrently's flag list by running concurrently --help. For the version, run concurrently --version.

Check out documentation and other usage examples in the docs directory.

API

concurrently can be used programmatically by using the API documented below:

concurrently(commands[, options])

  • commands: an array of either strings (containing the commands to run) or objects with the shape { command, name, prefixColor, env, cwd, ipc }.

  • options (optional): an object containing any of the below:

    • cwd: the working directory to be used by all commands. Can be overriden per command. Default: process.cwd().
    • defaultInputTarget: the default input target when reading from inputStream. Default: 0.
    • handleInput: when true, reads input from process.stdin.
    • inputStream: a Readable stream to read the input from. Should only be used in the rare instance you would like to stream anything other than process.stdin. Overrides handleInput.
    • pauseInputStreamOnFinish: by default, pauses the input stream (process.stdin when handleInput is enabled, or inputStream if provided) when all of the processes have finished. If you need to read from the input stream after concurrently has finished, set this to false. (#252).
    • killOthers: an array of exitting conditions that will cause a process to kill others. Can contain any of success or failure.
    • maxProcesses: how many processes should run at once.
    • outputStream: a Writable stream to write logs to. Default: process.stdout.
    • prefix: the prefix type to use when logging processes output. Possible values: index, pid, time, command, name, none, or a template (eg [{time} process: {pid}]). Default: the name of the process, or its index if no name is set.
    • prefixColors: a list of colors or a string as supported by chalk and additional style auto for an automatically picked color. If concurrently would run more commands than there are colors, the last color is repeated, unless if the last color value is auto which means following colors are automatically picked to vary. Prefix colors specified per-command take precedence over this list.
    • prefixLength: how many characters to show when prefixing with command. Default: 10
    • raw: whether raw mode should be used, meaning strictly process output will be logged, without any prefixes, coloring or extra stuff. Can be overriden per command.
    • successCondition: the condition to consider the run was successful. If first, only the first process to exit will make up the success of the run; if last, the last process that exits will determine whether the run succeeds. Anything else means all processes should exit successfully.
    • restartTries: how many attempts to restart a process that dies will be made. Default: 0.
    • restartDelay: how many milliseconds to wait between process restarts. Default: 0.
    • timestampFormat: a Unicode format to use when prefixing with time. Default: yyyy-MM-dd HH:mm:ss.ZZZ
    • additionalArguments: list of additional arguments passed that will get replaced in each command. If not defined, no argument replacing will happen.

Returns: an object in the shape { result, commands }.

  • result: a Promise that resolves if the run was successful (according to successCondition option), or rejects, containing an array of CloseEvent, in the order that the commands terminated.
  • commands: an array of all spawned Commands.

Example:

const concurrently = require('concurrently');
const { result } = concurrently(
  [
    'npm:watch-*',
    { command: 'nodemon', name: 'server' },
    { command: 'deploy', name: 'deploy', env: { PUBLIC_KEY: '...' } },
    {
      command: 'watch',
      name: 'watch',
      cwd: path.resolve(__dirname, 'scripts/watchers'),
    },
  ],
  {
    prefix: 'name',
    killOthers: ['failure', 'success'],
    restartTries: 3,
    cwd: path.resolve(__dirname, 'scripts'),
  },
);
result.then(success, failure);

Command

An object that contains all information about a spawned command, and ways to interact with it.
It has the following properties:

  • index: the index of the command among all commands spawned.

  • command: the command line of the command.

  • name: the name of the command; defaults to an empty string.

  • cwd: the current working directory of the command.

  • env: an object with all the environment variables that the command will be spawned with.

  • killed: whether the command has been killed.

  • state: the command's state. Can be one of

    • stopped: if the command was never started
    • started: if the command is currently running
    • errored: if the command failed spawning
    • exited: if the command is not running anymore, e.g. it received a close event
  • pid: the command's process ID.

  • stdin: a Writable stream to the command's stdin.

  • stdout: an RxJS observable to the command's stdout.

  • stderr: an RxJS observable to the command's stderr.

  • error: an RxJS observable to the command's error events (e.g. when it fails to spawn).

  • timer: an RxJS observable to the command's timing events (e.g. starting, stopping).

  • messages: an object with the following properties:

    • incoming: an RxJS observable for the IPC messages received from the underlying process.
    • outgoing: an RxJS observable for the IPC messages sent to the underlying process.

    Both observables emit MessageEvents.
    Note that if the command wasn't spawned with IPC support, these won't emit any values.

  • close: an RxJS observable to the command's close events. See CloseEvent for more information.

  • start(): starts the command and sets up all of the above streams

  • send(message[, handle, options]): sends a message to the underlying process via IPC channels, returning a promise that resolves once the message has been sent. See Node.js docs.

  • kill([signal]): kills the command, optionally specifying a signal (e.g. SIGTERM, SIGKILL, etc).

MessageEvent

An object that represents a message that was received from/sent to the underlying command process.
It has the following properties:

CloseEvent

An object with information about a command's closing event.
It contains the following properties:

  • command: a stripped down version of Command, including only name, command, env and cwd properties.
  • index: the index of the command among all commands spawned.
  • killed: whether the command exited because it was killed.
  • exitCode: the exit code of the command's process, or the signal which it was killed with.
  • timings: an object in the shape { startDate, endDate, durationSeconds }.

FAQ

  • Process exited with code null?

    From Node child_process documentation, exit event:

    This event is emitted after the child process ends. If the process terminated normally, code is the final exit code of the process, otherwise null. If the process terminated due to receipt of a signal, signal is the string name of the signal, otherwise null.

    So null means the process didn't terminate normally. This will make concurrently to return non-zero exit code too.

  • Does this work with the npm-replacements yarn, pnpm, or Bun?

    Yes! In all examples above, you may replace "npm" with "yarn", "pnpm", or "bun".