tinyexec
A tiny, higher-level interface around Node's child_process for running commands without the boilerplate.
Repository Health
Technical Analysis
tinyexec is a minimal wrapper around Node.js’s built-in child_process module, giving you an awaitable, async-iterable result object instead of manually wiring up streams and event listeners. Calling x('ls', ['-l']) returns a Result you can await directly for { stdout, stderr, exitCode }, or iterate line-by-line as output arrives, or pipe straight into another command.
The library deliberately stays small: it does not re-implement templating (that’s zx’s job) or add extensive helper surface area (that’s execa’s approach). Instead it focuses on correctness for the common case — cross-platform shebang resolution, safe argument escaping on Windows, PATH handling that includes local node_modules/.bin, abort-signal and timeout support, and an optional synchronous API (xSync) for blocking use cases like config loaders or build scripts.
What You Get
- An awaitable
Resultfromx(command, args, options)exposingstdout,stderr, andexitCodedirectly — no manual stream buffering - Async iteration over combined stdout/stderr output as it’s produced, in the order a terminal would show it
- A
pipe()method to chain a process’s output straight into another command’s input - Cross-platform command normalization on Windows — shebang detection,
node_modules/.bincmd-shim handling, and meta-character escaping - AbortSignal and timeout support that cleanly kills the child process and marks the result as aborted
- A synchronous
xSync/execSyncAPI for blocking call sites, with the same options surface minus signal/pipe/stdin-piping
Common Use Cases
- Build tools and CLIs that shell out to other binaries (linters, compilers, git) and need structured exit-code/output handling
- Scripts that pipe one command’s output into another (e.g.
lsintogrep) without manually wiring streams - Tooling that needs to abort a long-running subprocess on a timeout or user-triggered AbortSignal
- Cross-platform CLIs that must resolve and execute
node_modules/.binscripts or shebang-based executables correctly on Windows - Synchronous config/bootstrap scripts that need to run a command and read its output before continuing
Under The Hood
Architecture
tinyexec is organized as a handful of single-purpose modules under src/: main.ts holds the public x/xSync entry points and the ExecProcess class (which implements PromiseLike<Output> plus AsyncIterable<string> so a single object can be both awaited and iterated), normalize.ts isolates all Windows-specific command/argument normalization (shebang resolution, PATH searching, cmd.exe escaping), env.ts computes the environment passed to the child (merging process.env, prepending node_modules/.bin directories up the directory tree), and stream.ts provides a small combineStreams helper that merges stdout/stderr into one ordered Readable for the async iterator. ExecProcess centralizes process lifecycle: spawn() wires up node’s child_process.spawn, registers error/close handlers, and stores streams for later consumption by either then() (buffering full output) or the async iterator (line-by-line via readline). This single-class design keeps state (aborted/killed/exitCode) consistent regardless of which consumption style the caller picks.
Tech Stack
The package is pure TypeScript targeting Node.js >=18, built with tsdown into a single ESM dist/main.mjs plus .d.mts types (no CJS output, type: module in package.json). It has zero runtime dependencies — everything is built on Node’s node:child_process, node:stream, node:fs, node:path, and node:readline APIs. Dev tooling is thoroughly modern: typescript-eslint strict config, prettier for formatting, publint for package-export validation, and vitest (with @vitest/coverage-v8) for tests, with a CI matrix that also verifies a Bun build/test path alongside standard Node.js.
Code Quality
Tests live under src/test/ (main_test.ts, env_test.ts, normalize_test.ts, stream_test.ts) using vitest’s describe.for to run the same test suite against both the async (x) and sync (xSync) APIs, exercising real subprocess behavior (fixture scripts under test/fixtures/, including a shebang script and a Windows .cmd fixture) rather than mocking child_process. Error handling is explicit and typed: a dedicated NonZeroExitError class carries the exit/signal code and formats a human-readable message, and stream-read failures are deliberately swallowed only where a failed child spawn is the expected cause. GitHub Actions CI runs build, lint (tsc --noEmit + eslint + publint), and the test suite across Node 20/22/latest on both Ubuntu and Windows, plus a separate Bun build job — giving real cross-platform coverage for the Windows-specific normalization code.
What Makes It Unique
Unlike heavier alternatives such as execa, tinyexec deliberately avoids feature creep (no built-in templating, no file-based stdin/stdout helpers) in exchange for a near-zero footprint and a single unified Result type that is simultaneously awaitable and async-iterable — letting callers choose buffered or streaming consumption from the exact same call without a different API shape. Its Windows command normalization (adapted from patterns used by cross-spawn) is handled directly in a small, readable module rather than pulled in as an opaque dependency.
Used by 7 apps in this directory
ByteChef
Automation · AI Agents
Unified open-source platform for AI agent orchestration and workflow automation with 180+ connectors, MCP support, and durable execution.
Epicenter
Knowledge Management · Note Taking · Developer Tools
A local-first monorepo led by Whispering, an open-source speech-to-text app, built on an MIT toolkit that turns your data into plain Markdown and SQLite files you own instead of a database you rent.
Mastra Code
AI Code Assistants
"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.
Papra
Bookmarks Archiving
Self-hosted document archiving with email ingestion, OCR full-text search, and pluggable storage — store once, find anything.
Trigger.dev
Automation · AI Development · Developer Tools
Build and deploy fully-managed AI agents and background jobs in TypeScript — with no timeouts, durable retries, real-time observability, and elastic scaling built in.
Unlighthouse
Developer Tools
An open-source CLI that scans your entire website with Google Lighthouse, using smart sampling and a modern dashboard UI to audit every page instead of one URL at a time.
Webstudio
Design Tools · No Code Platforms
Open source visual development platform with complete CSS control, headless CMS integration, and full infrastructure ownership