shell-quote
Parses and quotes POSIX shell command strings, guarding against shell injection when building commands programmatically.
Repository Health
Technical Analysis
shell-quote is a zero-dependency Node.js utility with two complementary functions: quote(), which takes an array of arguments and escapes them into a single POSIX-shell-safe string, and parse(), which takes a shell command string and tokenizes it back into an array of arguments, handling single/double quotes, backslash escapes, environment variable interpolation, glob patterns, comments, and control operators like ||, &&, and |. It implements just enough of POSIX/bash quoting semantics to safely round-trip user- or config-supplied command strings without shelling out to an actual shell parser.
The library is widely used as a defensive building block anywhere a Node.js program needs to construct or interpret shell command lines from untrusted or dynamic input — task runners, build tools, CLI wrappers, and process-spawning utilities pull in shell-quote specifically to avoid hand-rolling shell-escaping logic, a notorious source of injection bugs. Because both quote() and parse() are pure functions with full TypeScript definitions and no runtime dependencies, it drops into any codebase with no extra installation weight or supply-chain surface.
What You Get
- quote(args) - Escapes an array of strings (or operator/glob/comment objects) into a single POSIX-shell-safe command string.
- parse(cmd, env, opts) - Tokenizes a shell command string into arguments, expanding
$VAR/${VAR}references against anenvobject or lookup function. - Control operator awareness - Recognizes shell operators like
||,&&,;,|,<,>, and<(as distinct{ op }tokens rather than plain strings. - Full TypeScript types - Ships
index.d.ts/parse.d.ts/quote.d.tswith no external@typespackage needed. - Zero runtime dependencies - No transitive packages, keeping install size and supply-chain surface minimal.
Common Use Cases
- Safely building shell commands from user input - Escaping filenames, flags, or config values before interpolating them into a command string.
- Parsing user- or config-supplied command strings - Splitting a single command-line string (e.g. from a config file) into an argv-style array for
spawn/execFile. - Implementing custom shell-like DSLs - Task runners and build tools use
parseto interpret pipeline/redirection syntax (|,>,&&) without embedding a real shell. - Environment variable interpolation - Expanding
$VAR/${VAR}references in a command string against a supplied environment object during parsing.
Under The Hood
Architecture
The package has a trivial two-module architecture: index.js re-exports quote.js and parse.js, each a single pure function with no internal object graph, class hierarchy, or shared mutable state. quote.js maps over an input array applying regex-driven escaping rules per token, while parse.js runs a hand-written scanner (a chunker regex plus a character-by-character state machine tracking quote/escape context) that emits a flat token array, with a separate reduce step to re-inject objects returned by a function-typed env callback via a randomized token-delimiter trick. There’s no dependency injection and no data flow beyond input string/array to output array/string — about as flat and low-blast-radius as a library gets.
Tech Stack
Plain CommonJS JavaScript targeting Node >=0.4, with zero runtime dependencies; devDependencies are entirely tooling — tape+nyc for tests, eslint for linting, tsc/@arethetypeswrong/cli to validate the checked-in .d.ts files against consumers, auto-changelog for changelog generation, and publish-safety guardrails (safe-publish-latest, npmignore, in-publish) typical of this maintainer’s package ecosystem. No build step is needed since hand-written JS ships directly alongside hand-written type declarations.
Code Quality
Tests live under test/ as one file per concern (quote, parse, env, env with a function, operators, comments, array-splitting), run with tape through nyc for coverage, with linting wired to run before tests so failures block the suite. Error handling in quote.js/parse.js is explicit and typed via thrown errors with descriptive messages for invalid token shapes and malformed ${...} substitutions rather than silent failure. JSDoc annotations back the hand-written type declarations, and CI runs lint, type-check, and test across a wide matrix of Node versions on every push.
API Design
The public surface is deliberately tiny — two functions, quote(args) and parse(cmd, env, opts) — requiring zero setup to get started, and the README explicitly documents footgun-avoidance (e.g. never re-quoting the output, steering Windows users toward execFile/spawn instead of shell strings). Type definitions are hand-authored and richly documented, including an unusual tuple-join type augmentation for literal string arrays, showing above-average attention to consumer type ergonomics; the main friction point is that parse’s object-token shapes require callers to branch on shape themselves since no discriminated helper is exported.
Used by 10 apps in this directory
CapRover
Developer Tools · Devops · Hosting Control Panel
Deploy any app, database, or website to your own server in minutes—no Docker or Linux expertise required.
claude-mem
AI Agents · AI Development
Give your AI coding agents persistent memory — claude-mem captures everything that happens during sessions, compresses it with AI, and surfaces the right context in every future session automatically.
Cline
AI Code Assistants
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.
Continue
Developer Tools · AI Development · AI Code Assistants
Open-source coding agent for VS Code, JetBrains, and CLI with support for 30+ LLM providers.
Dokploy
Devops · Hosting Control Panel · Security
Self-hosted PaaS that deploys apps and databases on your own VPS using Docker, Traefik, and multi-build-system orchestration
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.
openclaude
AI Agents · AI Code Assistants
Run Claude Code workflows against any LLM — OpenAI, Gemini, Ollama, and 200+ backends — from a single terminal-first CLI.
Scalar
Developer Tools
Beautiful, interactive OpenAPI documentation with a built-in offline-first API client and multi-language code generation — all in one open-source platform.
superset
AI Code Assistants · AI Development
Orchestrate an army of AI coding agents—Claude Code, Codex, Gemini CLI, and more—running simultaneously in isolated git worktrees from a single Electron desktop app.