Fast 0-deps bash parser written in TypeScript
npm install unbashimport { parse } from "unbash";
const ast = parse('if [ -f "$1" ]; then cat "$1"; fi');Result:
{
type: "Script",
commands: [{
type: "If",
clause: { type: "Command", name: { text: "[" }, ... },
then: { type: "Command", name: { text: "cat" }, ... }
}]
}Basic opinionated printer, does not preserve whitespace or comments (except shebang):
import { parse } from "unbash";
import { print } from "unbash/print";
const ast = parse('if [ -f "$1" ]; then cat "$1"; fi');
const script = print(ast);Result:
if [ -f "$1" ]; then
cat "$1"
fitree-sitter-bash is an excellent choice if you need:
- Incremental parsing
- CST output preserving all tokens and punctuation
- Granular error recovery that wraps errors in
ERRORnodes and continues parsing
unbash might be a good fit if you prefer:
- AST output
- A zero-dependency package that runs in any JS environment
- A typed TypeScript API
- Built-in parsing for command/process substitutions, coproc, Bash 5.3
${ cmd; },[[ ]],(( )), and extglob - Tolerant parsing that never throws and collects parse errors
sh-syntax is a WASM wrapper around the robust mvdan/sh Go parser. It is highly recommended if you need:
- Support for multiple shell dialects (bash, POSIX sh, mksh, Bats)
- Built-in formatting and pretty-printing (
print)
unbash might be a good fit if you prefer:
- A zero-dependency, synchronous API
- A detailed AST with structured word parts, parameter expansions, arithmetic expressions, and test expressions
bash-parser (last publish: 2017) and its fork @ericcornelissen/bash-parser (community dependency maintenance fork ❤️ now archived) might be interesting if you need:
- A POSIX-only mode that rejects bash-specific syntax
unbash might be a good fit if you prefer:
- A zero-dependency architecture
- A typed TypeScript API (ESM-only)
- Tolerant parsing that never throws and collects parse errors
- Structured AST nodes for parameter expansions, arithmetic expressions, and
[[ ]]test expressions - Support for many additional syntax features (like herestrings, C-style for loops,
select, process substitution, etc. etc.)
Relative performance comparison (on Apple M1 Pro/32GB), unbash is x times faster:
| Parser | short | advanced | medium | large |
|---|---|---|---|---|
| tree-sitter-bash (native) | 13x | 9x | 4x | 5x |
| tree-sitter-bash (WASM) | 16x | 12x | 8x | 8x |
| sh-syntax | 2136x | 1537x | 8x | 4x |
| bash-parser | 256x | N/A | N/A | N/A |
| @ericcornelissen/bash-parser | 267x | N/A | N/A | N/A |
Run the benchmarks using Node.js v22:
pnpm install
node bench/all.tsunbash is 53K minified, 13KB gzipped.
ISC