execa

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

Library
npm
v10.2.1
7,623 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
90 /100 Excellent
Development Activity 100
Maintenance 84
Community 76
Maturity 60
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
90 /100 Excellent
Architecture 88
Code Quality 92
Innovation 90
Learning Curve 88

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 43 apps in this directory

TypeScript
96%
MIT

likec4

Developer Tools · Devops

5,954

Define your software architecture as code and get always up-to-date, interactive C4 diagrams generated automatically from a DSL.

View details
89
Repo Health
83
Technical
78
Dependency
Built with
TypeScript 96%
Updated 5 days ago
TypeScript
98%
Other

LobeHub

AI Assistants · Automation · Productivity

83,455

Your Chief Agent Operator — build, schedule, and collaborate with an entire AI team in one self-hostable workspace.

View details
92
Repo Health
81
Technical
65
Dependency
Built with
TypeScript 98%
Updated 5 days ago
JavaScript
55%
Other

Lokus

Knowledge Management · Note Taking

829

Local-first note-taking with graph view, canvas & AI plugins—your Markdown files, zero telemetry, blazing-fast Rust performance.

View details
75
Repo Health
75
Technical
64
Dependency
Built with
JavaScript 55%
HTML 21%
Rust 12%
Updated 2 months ago
TypeScript
99%
Apache 2.0

Mastra Code

AI Code Assistants

29,041

"A coding agent that never compacts" — a terminal-based AI coding agent built on the Mastra framework, with Observational Memory instead of context compaction, multi-model support, and OAuth login for Claude Max or ChatGPT Plus.

View details
90
Repo Health
73
Technical
65
Dependency
Built with
TypeScript 99%
Updated 5 days ago
TypeScript
87%
MIT

medusa

Ecommerce

36,897

The most flexible open-source commerce platform — build B2C, B2B, and marketplace applications with modular, composable commerce primitives.

View details
94
Repo Health
87
Technical
63
Dependency
Built with
TypeScript 87%
JavaScript 12%
Updated 6 days ago
TypeScript
95%
Apache 2.0

NemoClaw

AI Agents · AI Development

22,823

Run AI coding agents like OpenClaw and Hermes securely inside NVIDIA OpenShell sandboxes with a hardened blueprint, routed inference, and lifecycle management through a single CLI.

View details
79
Repo Health
87
Technical
71
Dependency
Built with
TypeScript 95%
Updated 5 days ago
TypeScript
99%
Other

NocoBase

Low Code Platforms · No Code Platforms

24,686

Open-source AI + no-code platform that lets coding agents and people collaborate to build business systems fast on proven infrastructure.

View details
94
Repo Health
81
Technical
63
Dependency
Built with
TypeScript 99%
Updated 5 days ago
TypeScript
98%
Other

Novu

Developer Tools

40,195

Open-source communication infrastructure that connects your products and AI agents to every channel your users live on — Inbox, Email, SMS, Push, Chat, and more.

View details
93
Repo Health
80
Technical
64
Dependency
Built with
TypeScript 98%
Updated 5 days ago
TypeScript
99%
Other

openclaude

AI Agents · AI Code Assistants

34,123

Run Claude Code workflows against any LLM — OpenAI, Gemini, Ollama, and 200+ backends — from a single terminal-first CLI.

View details
87
Repo Health
78
Technical
71
Dependency
Built with
TypeScript 99%
Updated 5 days ago

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