execa

A modern process-execution library for Node.js with template-string syntax and zero shell-injection risk.

Library
npm
v10.0.1
7,602stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
76/100Good
Development Activity68
Maintenance76
Community60
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
90/100Excellent
Architecture88
Code Quality92
Innovation90
Learning Curve88

Execa is a process-execution library for Node.js that wraps the core child_process module in an ergonomic, promise-based API. It replaces manual escaping and string-concatenated shell commands with tagged-template syntax, so arguments are always passed as separate argv entries instead of being interpolated into a shell string — removing an entire class of shell-injection bugs by design rather than by convention.

Beyond basic execution, Execa adds features shells don’t have out of the box: piping between subprocesses while still retrieving each intermediate result, splitting output into text lines or iterating over them as they arrive, sending typed messages to and from Node.js child processes over IPC, and gracefully terminating subprocesses on cancellation instead of leaving orphaned children behind. It ships both async (execa) and sync (execaSync) variants sharing one options API, plus a script-style $ interface for shell-like one-liners without giving up any of the safety guarantees.

What You Get

  • Tagged-template command syntax (execacmd ${arg}) with automatic argument escaping and zero shell-injection risk
  • Synchronous (execaSync) and asynchronous (execa) execution sharing one identical options API
  • Subprocess piping via .pipe with access to every intermediate result, not just the final output
  • Built-in text-line splitting/iteration, binary output support, and file-based stdin/stdout redirection
  • IPC message exchange with child Node.js processes plus cancellation-aware graceful termination

Common Use Cases

  • Running build/test tool commands (npm scripts, linters, compilers) from a Node.js CLI or task runner
  • Writing cross-platform shell scripts in JavaScript instead of Bash, via the $ script interface
  • Chaining multiple subprocesses together (e.g. build | sort | head) while inspecting each stage’s output
  • Spawning and communicating with long-running Node.js worker subprocesses over IPC

Under The Hood

Architecture Execa is built as a thin factory/dispatch layer over independently testable subsystems. lib/methods/create.js exposes a single createExeca(mapArguments, boundOptions, deepOptions, setBoundExeca) factory that every public export (execa, execaSync, execaNode, $) is built from; each variant differs only in how it maps arguments and merges options, not in a separately maintained code path. Calls are parsed as either tagged-template or classic (file, args, options) form, options are merged in layers (deep defaults, bound options, call-time options) via lib/methods/bind.js, and dispatch lands in execaCoreSync or execaCoreAsync. Cross-cutting concerns — stdio resolution (lib/stdio, lib/resolve), termination (lib/terminate: graceful signals, descendant killing, timeouts), IPC (lib/ipc), piping (lib/pipe), stream transforms (lib/transform), and verbose logging (lib/verbose) — are each isolated in their own directory and consumed through the shared merged-options object, so changing the options-merging logic ripples through all of them, but each subsystem itself stays independently readable and testable.

Tech Stack Pure ESM (type: module) targeting Node.js 22+, with no runtime framework — everything is built directly on node:child_process and node:stream. Type definitions in index.d.ts are hand-written rather than compiled from TypeScript source. Dependencies are a set of small, single-purpose packages from the same ecosystem (@sindresorhus/merge-streams, human-signals, is-plain-obj, is-stream, npm-run-path, pretty-ms, signal-exit, yoctocolors, figures, get-stream), each handling one narrow concern rather than a general-purpose utility belt. Linting runs through xo, tests through ava with c8 coverage, type-checking through tsd plus tsc, and CI runs all of it via GitHub Actions with coverage reported to Codecov.

Code Quality Tests are organized per-feature under test/, mirroring the lib/ module layout, with ava deliberately run single-threaded and at concurrency 1 — appropriate given the tests exercise real OS-level process and signal behavior rather than pure functions. Type correctness is verified separately from runtime behavior via tsd type-assertion tests plus a plain tsc check. Error handling is explicit and typed: dedicated ExecaError/ExecaSyncError classes carry shortMessage, exit code, signal, and the original cause, a DiscardedError sentinel distinguishes internal control-flow interruptions from real failures, and a well-known Symbol makes isExecaError checks work safely across realms instead of relying on instanceof. Naming and one-export-per-file conventions are consistent throughout. CI enforces lint, unit tests, and type checks on every push — this is a comprehensively tested and typed codebase.

What Makes It Unique Execa’s tagged-template syntax passes interpolated values as separate argv entries rather than concatenating them into a shell string, removing shell-injection risk structurally instead of relying on the caller to escape input correctly — a guarantee most process-execution wrappers don’t offer. Its sync and async entry points share one argument-parsing and options-merging path rather than being separately maintained implementations that can drift apart. Piping exposes pipedFrom so every intermediate stage of a subprocess chain remains inspectable, unlike native shell pipes which discard everything but the final output. IPC helpers (sendMessage, getOneMessage, getEachMessage) and cancellation-aware graceful termination (cancelSignal plus gracefulCancel) give it primitives well beyond a typical wrapper around child_process.spawn.

Used by 41 apps in this directory

TypeScript
49%
MPL 2.0

Artillery

Devops · Developer Tools

9,071

Cloud-scale load testing and functional testing for APIs, WebSockets, gRPC, and headless browsers, distributed across AWS Lambda or Fargate with zero infrastructure to manage.

View details
88
Repo Health
73
Technical
68
Dependency
Built with
TypeScript49%
JavaScript48%
Updated 1 weeks ago
TypeScript
69%
Other

Budibase

Low Code Platforms · No Code Platforms

28,260

Build AI agents, automations, and internal apps on a single open-source platform with full self-hosting control.

View details
91
Repo Health
81
Technical
63
Dependency
Built with
TypeScript69%
Svelte26%
Updated 2 days ago
Rust
67%
MIT

Bun

Developer Tools

95,895

An all-in-one JavaScript and TypeScript toolkit — one Rust-and-JavaScriptCore binary that replaces Node.js, npm, a bundler, and a test runner with faster equivalents.

View details
92
Repo Health
91
Technical
64
Dependency
Built with
Rust67%
C++19%
Updated yesterday
TypeScript
96%
Other

Cal.diy

Scheduling

48,218

The 100% MIT-licensed, community-driven scheduling platform — self-host your own booking infrastructure with no enterprise strings attached.

View details
95
Repo Health
86
Technical
65
Dependency
Built with
TypeScript96%
Updated yesterday
TypeScript
98%
Apache 2.0

Cline

AI Code Assistants

67,585

An open-source AI coding agent that lives in your editor and terminal — reads and edits your codebase, runs commands, browses the web, and requires human approval for every action by default.

View details
89
Repo Health
74
Technical
65
Dependency
Built with
TypeScript98%
Updated 2 days ago
TypeScript
84%
Apache 2.0

Continue

Developer Tools · AI Development · AI Code Assistants

35,808

Open-source coding agent for VS Code, JetBrains, and CLI with support for 30+ LLM providers.

View details
81
Repo Health
88
Technical
62
Dependency
Built with
TypeScript84%
Updated yesterday
TypeScript
45%
Other

Convex Backend

Developer Tools · Databases

12,494

Open-source reactive database that lets developers build live-updating apps with pure TypeScript, strong consistency, and real-time subscriptions—no separate API layer required.

View details
87
Repo Health
82
Technical
68
Dependency
Built with
TypeScript45%
Rust43%
Updated 2 days ago
TypeScript
81%
Other

Directus

CMS · Low Code Platforms

37,783

Connect any SQL database and get instant REST and GraphQL APIs, a visual management Studio, and a native MCP server for AI agents — free for most organizations.

View details
92
Repo Health
82
Technical
76
Dependency
Built with
TypeScript81%
Vue18%
Updated 3 days ago
Ruby
60%
GPL 2.0

Discourse

Community

47,793

Open-source community platform with dynamic trust levels, real-time chat, and a powerful plugin architecture for self-hosted forums.

View details
89
Repo Health
89
Technical
67
Dependency
Built with
Ruby60%
JavaScript32%
Updated today

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search