Format strings as POSIX shell argument literals.
Warning: This library is for display and formatting purposes only. Do NOT use it to build commands for actual shell execution. If you need to execute commands safely, use proper APIs like
execFile()with argument arrays, or dedicated security-focused libraries.
This library is intended for:
# npm
npm install @suin/shell-escape-arg
# bun
bun add @suin/shell-escape-arg
# pnpm
pnpm add @suin/shell-escape-arg
import shellEscapeArg from "@suin/shell-escape-arg";
// Safe strings pass through unchanged
shellEscapeArg("abc"); // "abc"
shellEscapeArg("日本語"); // "日本語"
// Strings with spaces or special chars are quoted
shellEscapeArg("a b"); // "'a b'"
shellEscapeArg("$HOME"); // "'$HOME'"
shellEscapeArg("*.txt"); // "'*.txt'"
// Single quotes are escaped with '\''
shellEscapeArg("O'Reilly"); // "'O'\\''Reilly'"
// Empty string becomes ''
shellEscapeArg(""); // "''"
// Leading tilde is quoted to prevent expansion
shellEscapeArg("~user"); // "'~user'"
import shellEscapeArg from "@suin/shell-escape-arg";
function logCommand(program: string, args: string[]): void {
const formatted = args.map(shellEscapeArg).join(" ");
console.log(`Would run: ${program} ${formatted}`);
}
logCommand("grep", ["-r", "hello world", "*.txt"]);
// Output: Would run: grep -r 'hello world' '*.txt'
import shellEscapeArg from "@suin/shell-escape-arg";
function generateInstallDocs(packageName: string): string {
return `
## Installation
\`\`\`bash
npm install ${shellEscapeArg(packageName)}
\`\`\`
`;
}
The library uses POSIX single-quote formatting:
| Input | Output | Reason |
|---|---|---|
abc |
abc |
Alphanumeric – no quoting needed |
日本語 |
日本語 |
Unicode text – no quoting needed |
a b |
'a b' |
Contains space – quoted |
$HOME |
'$HOME' |
Contains $ – quoted |
*.txt |
'*.txt' |
Contains * – quoted |
O'Reilly |
'O'\''Reilly' |
Contains ' – escaped as '\'' |
| `` | '' |
Empty string – quoted |
~user |
'~user' |
Starts with ~ – quoted |
Inside POSIX single quotes, everything is literal except the single quote itself:
$VAR stays as $VAR`cmd` stays as `cmd`\n stays as \n* stays as *The library quotes strings that contain:
' " \ $ ` | & ; < > ( ) * ? [ ] { } ! #import shellEscapeArg from "@suin/shell-escape-arg";
// Throws TypeError for non-string input
shellEscapeArg(123); // TypeError: escape: arg must be a string
shellEscapeArg(null); // TypeError: escape: arg must be a string
// Throws Error for NUL character (cannot exist in POSIX arguments)
shellEscapeArg("a\0b"); // Error: escape: arg must not include NUL (\u0000)
This library formats a single argument. It does not parse or build command lines.
Produces output for POSIX-compatible shells (sh, bash, zsh, dash, ksh). Not suitable for:
This library does not provide security guarantees. For executing commands:
// ✓ Use execFile with argument arrays (no shell involved)
import { execFile } from "child_process";
execFile("grep", ["-r", pattern, filename]);
// ✓ Use Bun's $ with template literals (handles escaping internally)
import { $ } from "bun";
await $`grep -r ${pattern} ${filename}`;
// ✗ Do NOT use this library for execution
import { exec } from "child_process";
exec(`grep ${shellEscapeArg(pattern)} ${shellEscapeArg(filename)}`); // Don't do this
See the full API documentation.
MIT
Issues and pull requests are welcome on GitHub.