CLI tool
open-cli-tools/concurrently avatar
open-cli-tools/concurrently

Concurrently: Running Multiple Commands with Managed Output

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

7,857 stars279 forksTypeScriptMIT

At a glance

What is it?
A Node.js tool for managing parallel command execution with readable output control. Concurrently captures output from multiple processes, prefixes it for clarity, and can kill all commands if one fails.
Who is it for?
Use Concurrently when you need to orchestrate multiple long-running processes (dev servers, watchers) from a single npm script or CLI invocation, especially on teams using Windows where background job control differs. Avoid it for sequential task pipelines or when you need process isolation beyond what it provides.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 17 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Running Multiple npm Scripts in Parallel Across Platforms

Running multiple npm scripts in parallel has long been a friction point. The shell background operator `&` spawns processes but leaves their output interleaved and unreadable, and if one process crashes, the others keep running silently. Teams working across Linux, macOS, and Windows face platform-specific syntax: Unix shells accept `cmd1 & cmd2`, but Windows PowerShell and CMD require different patterns. Concurrently abstracts this away by providing a single command that works identically across platforms, labels each process's output with a prefix so you can track which command produced which line, and offers a `--kill-others` flag to stop all processes if any one exits.

How it orchestrates processes

Concurrently spawns each command in its own child process using Node's `child_process` module, then subscribes to their stdout and stderr streams. Each line of output is tagged with the process's name or index, colored for distinction using the Chalk color library, and written to a unified output stream. The tool uses RxJS observables (version 7.8.2) internally to handle the asynchronous events of multiple processes ending at different times. The `tree-kill` package (version 1.2.2) ensures that when you use `--kill-others`, it terminates not just the child process but its entire process tree (including grandchildren), which is essential for cleaning up processes that spawn their own subprocesses. The `shell-quote` package handles proper quote escaping across platforms, and `supports-color` detects terminal color capability so output adapts to the environment. The `yargs` command-line parser (version 18.0.0) handles flag parsing and provides help text.

Install and Quote Commands Correctly on Your Platform

Concurrently is distributed as an npm package and works on Node 22 or later. Install it globally to use it system-wide, or as a dev dependency in your project.

bash
npm i -g concurrently

Once installed, you can run commands directly from the shell. Remember that on all platforms, each command must be quoted separately:

bash
concurrently 'command1 arg' 'command2 arg'

On Windows, use double quotes instead of single quotes:

bash
concurrently "command1 arg" "command2 arg"

Within a package.json script, escape the double quotes:

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

Run any shell command, not just npm scripts. The tool reads from process.stdin by default, so you can send input to processes (configure with `--handle-input` to direct stdin to a specific process by its index, default `0`).

Key configuration options

Concurrently's behavior is controlled by command-line flags. The `--kill-others` flag is one of the most useful: when any process exits with status 0 or non-zero (or just one of those outcomes), it terminates the rest. Set it to `--kill-others-on-fail` to stop all processes only if one exits with a non-zero code. The `--prefix` option controls how output is labeled; values include `index` (0, 1, 2...), `pid` (process ID), `time`, `command` (first 10 characters by default, adjustable with `--prefix-length`), or `name` (from the command object if using the API). Prefix templates like `[{color}{name}{/color}]` let you customize output format and apply colors selectively. The `--success-condition` flag determines success: `first` means the first process to exit determines the exit status; `last` means the status of the final exiting process matters. The `--prefix-colors` option accepts Chalk color functions like `rgb(255,0,0).bold` or hex colors like `#FF0000`, and if there are more processes than colors, the last one repeats unless set to `auto` for automatic color variation. By default, all processes must succeed. The `--raw` flag disables all prefixing and coloring, outputting raw text only. For limiting concurrent execution, `--max-processes N` runs at most N processes at once, queuing the rest. The `--cwd` option sets a working directory for all commands unless overridden per-command.

Using it programmatically

Concurrently exports a function accessible as the default export from the main entry point (`dist/lib/index.js`), which takes an array of commands and an optional options object. Commands can be strings (simple command strings) or objects with properties like `command`, `name`, `prefixColor`, `cwd`, `env`, and `ipc` for inter-process communication. This API is useful in build scripts or custom tooling where you want finer control than the CLI provides. The function returns a Promise that resolves or rejects based on the success condition and `killOthersOn` setting. The programmatic interface accepts the same options as the CLI: `cwd` sets the working directory for a specific command, the `env` object merges additional environment variables for that command's execution, `outputStream` directs output to a writable stream instead of stdout, and `inputStream` reads input from a custom source instead of stdin. The shell executable can be set globally or per-command, and shell resolution falls back to environment variables like `npm_config_script_shell` (set by npm) or platform defaults.

Where it stops short

Concurrently manages output and lifecycle, not task dependencies. If one process needs output from another before starting, you must handle that sequencing separately. The tool runs commands in parallel from the moment it launches; it cannot wait for one to reach a specific state (like a server listening on a port) before starting the next. Output prefixing is line-based, so if a process outputs partial lines without newlines, the prefix may appear in unexpected places. On systems with many processes, the number of file descriptors used by the tool increases linearly, and I/O bottlenecks can emerge if all processes output heavily at once.

Alternatives

GNU Parallel and Xargs handle parallel execution of many short-lived tasks but lack the output management for long-running processes. The Makefile approach using the `.PHONY` target and subshells gives fine-grained task dependencies but is verbose and less portable across shells. Foreman and similar process managers work better for production deployments where you need logging, restart policies, and monitoring, not for local development.

Recent Releases and MIT License

The last push was 2026-09-15, and recent releases (v10.0.5 in August) show active maintenance. Concurrently is MIT-licensed, permitting any use including commercial deployment. The code is TypeScript, compiled to JavaScript in the dist/ directory.

Editorial conclusion

Use Concurrently when you need to orchestrate multiple long-running processes (dev servers, watchers) from a single npm script or CLI invocation, especially on teams using Windows where background job control differs. Avoid it for sequential task pipelines or when you need process isolation beyond what it provides. Before deploying in your CI pipeline, verify that your shell quotes arguments correctly on your platform and test that all processes terminate cleanly.

Frequently asked questions

Can I use Concurrently to run npm scripts on Windows?

Yes. Concurrently is cross-platform and handles Windows, macOS, and Linux. Use double quotes on Windows instead of single quotes for command arguments.

What happens if I do not use --kill-others?

Without --kill-others, all processes continue running even if one exits. The tool reports each process's exit status but does not terminate the others.

How do I assign different environment variables to each command?

Pass an array of command objects with an env property in the API. This sets environment variables for that specific process without affecting others.

Does Concurrently work with shell pipes and redirections?

Concurrently passes each quoted command to a shell (bash, sh, or cmd.exe depending on your platform), so pipes, redirections, and other shell syntax work as expected within the quotes.

Official sources

  1. License: MIT
  2. open-cli-tools/concurrently on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/open-cli-tools-concurrently.svg)](https://hysenlabs.com/projects/open-cli-tools-concurrently)