# parallel-park

> Parallel/concurrent async work, optionally using multiple processes

Latest version **0.3.1** (published 2026-01-17) · MIT license · 0 weekly downloads

## Install

```sh
npm install parallel-park
pnpm add parallel-park
yarn add parallel-park
bun add parallel-park
```

## Health

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

Positive: has types; no vulnerabilities; high maintenance score; high quality score.

Warnings: low downloads; no esm support; pre 1.0.

## Facts

| | |
|---|---|
| Version | 0.3.1 |
| Published | 2026-01-17 |
| First published | 2022-02-19 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 3 |
| Unpacked size | 8.7 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 10 |
| Author | Lily Skye |
| Maintainers | suchipi |
| Keywords | parallel, concurrent, thread, multithread, worker, process, child, concurrency, co-operative, promise, map |

## Links

- npm: https://www.npmjs.com/package/parallel-park
- Repository: https://github.com/suchipi/parallel-park
- Homepage: https://github.com/suchipi/parallel-park#readme
- Issues: https://github.com/suchipi/parallel-park/issues
- npm.io page: https://npm.io/package/parallel-park

## Dependencies (3)

- [debug](https://npm.io/package/debug.md) ^4.4.3
- [@parallel-park/run-jobs](https://npm.io/package/@parallel-park/run-jobs.md) 0.3.1
- [@parallel-park/in-child-process](https://npm.io/package/@parallel-park/in-child-process.md) 0.3.1

## Alternatives

- [cron](https://npm.io/package/cron.md) — 4.9M weekly downloads
- [@vercel/queue](https://npm.io/package/@vercel/queue.md) — 731.6K weekly downloads
- [create-sonicjs](https://npm.io/package/create-sonicjs.md) — 1.6K weekly downloads
- [@exellix/jobs-api](https://npm.io/package/@exellix/jobs-api.md) — 941 weekly downloads
- [@forwardimpact/libskill](https://npm.io/package/@forwardimpact/libskill.md) — 575 weekly downloads

## Recent versions

- 0.3.1 (latest) — 2026-01-17
- 0.3.0 — 2026-01-15
- 0.2.2 — 2024-05-31
- 0.2.1 — 2024-05-11
- 0.2.0 — 2022-02-23
- 0.1.0 — 2022-02-22
- 0.0.0 — 2022-02-19

## README

# parallel-park

Parallel/concurrent async work, optionally using multiple processes

## Usage

`parallel-park` exports two functions: `runJobs` and `inChildProcess`.

### `runJobs`

`runJobs` is kinda like `Promise.all`, but instead of running everything at once, it'll only run a few Promises at a time (you can choose how many to run at once). It's inspired by [Bluebird's Promise.map function](http://bluebirdjs.com/docs/api/promise.map.html).

To use it, you pass in an iterable (array, set, generator function, etc) of inputs and a mapper function that transforms each input into a Promise. You can also optionally specify the maximum number of Promises to wait on at a time by passing an object with a `concurrency` property, which is a number. The concurrency defaults to 8.

When using an iterable, if the iterable yields a Promise (ie. `iterable.next() returns { done: false, value: Promise }`), then the yielded Promise will be awaited before being passed into your mapper function. Additionally, async iterables are supported; if `iterable.next()` returns a Promise, it will be awaited.

```ts
import { runJobs } from "parallel-park";

const inputs = ["alice", "bob", "carl", "dorsey", "edith"];
const results = await runJobs(
  inputs,
  async (name, index, inputsCount) => {
    // Do whatever async work you want inside this mapper function.
    // In this case, we use a hypothetical "getUser" function to
    // retrieve data about a user from some web API.
    console.log(`Getting fullName for ${name}...`);
    const user = await getUser(name);
    return user.fullName;
  },
  // This options object with concurrency is an optional argument.
  // If unspecified, it defaults to { concurrency: 8 }
  {
    // This number specifies how many times to call the mapper
    // function before waiting for one of the returned Promises
    // to resolve. Ie. "How many promises to have in-flight concurrently"
    concurrency: 2,
  }
);
// Logs these two immediately:
//
// Getting fullName for alice...
// Getting fullName for bob...
//
// But, it doesn't log anything else yet, because we told it to only run two things at a time.
// Then, after one of those Promises has finished, it logs:
//
// Getting fullName for carl...
//
// And so forth, until all of them are done.

// `results` is an Array of the resolved value you returned from your mapper function.
// The indices in the array correspond to the indices of your inputs.
console.log(results);
// Logs:
// [
//   "Alice Smith",
//   "Bob Eriksson",
//   "Carl Martinez",
//   "Dorsey Toth",
//   "Edith Skalla"
// ]
```

### `inChildProcess`

`inChildProcess` is a function that you pass a function into, and it spawns a separate node process to run your function in. Once your function has completed, its return/resolved value will be sent back to the node process you called `inChildProcess` from.

```ts
import { inChildProcess } from "parallel-park";

const result = await inChildProcess(() => {
  return 2 + 2;
});

console.log(result); // 4
```

Your function can also return a Promise:

```ts
// Either by returning a Promise directly...
await inChildProcess(() => {
  return Promise.resolve(2 + 2);
});

// Or by using an async function, which returns a Promise that resolves to the function's return value
await inChildProcess(async () => {
  return 2 + 2;
});
```

> ⚠️ NOTE: The return value of your function must be JSON-serializable, or else it won't make it across the gap between the parent node process and the child one.

The function you pass into `inChildProcess` will be executed in a separate node process; as such, it won't be able to access variables defined in the file calling `inChildProcess`:

```ts
const myName = "Lily";

await inChildProcess(() => {
  // Throws an error: myName is not defined
  return myName + "!";
});
```

To work around this, you can pass an object into `inChildProcess` as its first argument, before the function. When called this way, the function will receive that object:

```ts
await inChildProcess({ myName: "Lily" }, (data) => {
  const myName = data.myName;

  // No longer throws an error
  return myName + "!";
});
```

It's common to use object shorthand and destructuring syntax when passing values in:

```ts
const myName = "Lily";

await inChildProcess({ myName }, ({ myName }) => {
  return myName + "!";
});
```

> ⚠️ NOTE: The values in your input object must be JSON-serializable, or else they won't make it across the gap between the parent node process and the child one.

Because the inputs have to be JSON-serializable, you may run into an issue if trying to use an external module within the child process:

```ts
const util = require("util");

await inChildProcess({ util }, ({ util }) => {
  const someData = { something: true };
  // Throws an error: util.inspect is not a function
  return util.inspect(someData);
});
```

To work around this, call `require` inside the child process function:

```ts
await inChildProcess(() => {
  const util = require("util"); // the require is inside the function now

  const someData = { something: true };

  // No longer throws an error
  return util.inspect(someData);
});
```

If you want to use the external module both inside of the child process and outside of it, `require` it in both places:

```ts
const util = require("util");

await inChildProcess(() => {
  const util = require("util");

  const someData = { something: true };

  // No longer throws an error
  return util.inspect(someData);
});
```

The `require` inside of the child process can also be used to load stuff from your own code into the child process:

```ts
const file = "/home/lily/hello.txt";

await inChildProcess({ file }, async ({ file }) => {
  const processFile = require("./process-file");

  const results = await processFile(file);
  console.log(results);
  return results;
});
```

## License

MIT

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