Registry / serialization / unbash

unbash

JSON →
library2.2.0jsnpmunverified

unbash is a fast, zero-dependency library written in TypeScript for parsing Bash scripts into a structured Abstract Syntax Tree (AST). Currently stable at version 2.2.0, it differentiates itself by offering a pure JavaScript/TypeScript implementation without WASM or native bindings, providing a fully typed API, and delivering high performance, often outperforming alternatives by a significant margin. Its release cadence follows a typical Semantic Versioning approach, with updates for features and bug fixes. Key differentiators include its AST-centric output (unlike CST-focused parsers), tolerant parsing that collects errors rather than throwing exceptions, and built-in support for advanced Bash syntax such as process substitutions, coproc, `[[ ]]` test expressions, `(( ))` arithmetic evaluations, and extglob. It is designed for environments requiring a lightweight, synchronous parsing solution. While it excels at AST generation and speed, it does not offer incremental parsing, full token preservation for CSTs, or multi-shell dialect support (e.g., pure POSIX sh), features found in libraries like tree-sitter-bash or sh-syntax. It requires Node.js v14 or higher and maintains a small bundle size (13KB gzipped).

npm install unbash
INSTALL
IMPORT
SIG · UNBASH
U
unbash
serializationjavascriptv2.2.0
Install
Import
Disk
Pass rate
0/ 6
Env Coverage0 / 6
glibc
1822
musl
1822
Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
node 18226 runs
build_error
glibc
node 18226 runs
build_error
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

parse
import { parse } from 'unbash'
const { parse } = require('unbash')
unbash is an ESM-first package since v2. Use named imports.
print
import { print } from 'unbash/print'
import { print } from 'unbash'
The `print` utility is a sub-module and must be imported from 'unbash/print'.
Script
import { type Script } from 'unbash'
Type imports are used for type definitions like `Script`.

Parses a sample Bash script into an AST, checks for collected parsing errors, and then prints the AST back into a formatted Bash script string, demonstrating core functionality and tolerant error handling.

import { parse, type Script } from "unbash"; import { print } from "unbash/print"; // Define a Bash script string to parse. const bashScript = 'if [ -f "$1" ]; then\n echo "File exists: $1"\n cat "$1"\nelse\n echo "File not found: $1"\nfi'; // Parse the script into an AST (Abstract Syntax Tree). // unbash performs tolerant parsing, meaning it attempts to create an AST even with syntax errors, // collecting any issues in the 'errors' property of the returned object. const ast: Script = parse(bashScript); // Check if any parsing errors occurred. if (ast.errors && ast.errors.length > 0) { console.warn("Parsing errors detected:", ast.errors); // Depending on your application, you might want to stop here or attempt to recover. } else { console.log("Successfully parsed script into AST (truncated):\n", JSON.stringify(ast, null, 2).substring(0, 500) + "..."); } // Use the built-in printer to convert the AST back into a Bash script string. // Note: The `print` function is opinionated and will reformat the script, // not necessarily preserving original whitespace, comments, or exact layout. const printedScript = print(ast); console.log("\nRe-printed script from AST:\n", printedScript); // Demonstrate parsing a script with an obvious error to show tolerant parsing const erroneousScript = 'for i in 1 2 3; do echo $i fi;'; // Missing 'done' const erroneousAst = parse(erroneousScript); if (erroneousAst.errors && erroneousAst.errors.length > 0) { console.error("\nDetected errors in erroneous script example:", erroneousAst.errors); }
Debug
Known issues
breakingunbash is an ES Module (ESM) package since version 2. Attempting to `require()` it in a CommonJS environment will result in a runtime error.
fix
Migrate your project to use ES Modules (`"type": "module"` in `package.json`) and use `import` statements, or use dynamic `import('unbash')` in a CommonJS context.
affects: >=2.0.0
gotchaThe `print` utility is an opinionated formatter. It does not preserve original whitespace, comments (except shebang), or exact input formatting. It generates a normalized Bash script from the AST.
fix
Understand that `print` is for generating a standardized output script from an AST, not for round-trip fidelity of the original script's formatting. Do not rely on it to preserve non-semantic elements.
affects: *
gotchaunbash uses tolerant parsing. This means syntax errors do not throw exceptions but are collected within the `errors` property of the returned AST object. Your application must explicitly check this property.
fix
Always check `if (ast.errors && ast.errors.length > 0)` after calling `parse()` to detect and handle any syntax issues present in the input script.
affects: *
gotchaunbash generates an Abstract Syntax Tree (AST) and does not support incremental parsing or Concrete Syntax Tree (CST) output. If you need full token preservation, granular error recovery with `ERROR` nodes, or incremental parsing for editor integration, alternatives like `tree-sitter-bash` might be more suitable.
fix
Evaluate your parsing requirements. unbash is optimized for speed and AST generation for structural analysis, not for preserving every token or supporting incremental updates.
affects: *
gotchaunbash is specifically designed for Bash syntax. It does not provide inherent support for other shell dialects such as pure POSIX sh, mksh, or others. For multi-dialect support, consider alternatives like `sh-syntax`.
fix
Ensure that the scripts you are parsing are predominantly Bash-compliant. For parsing diverse shell dialects, investigate libraries that offer broader shell compatibility.
affects: *
Errors
Common errors & fixes
Error [ERR_REQUIRE_ESM]: require() of ES Module ... from ... not supported. Instead, change the require of ... to a dynamic import() or top-level import statement.
Attempting to use `require('unbash')` in a CommonJS module, but unbash v2+ is an ES Module.
fix
Update your import statement to `import { parse } from 'unbash';` and ensure your Node.js project is configured for ESM (e.g., by adding `"type": "module"` to your `package.json`).
SyntaxError: The requested module 'unbash' does not provide an export named 'parse'
Incorrectly trying to import `parse` as a default export or using a CommonJS-style named import when the package uses named ESM exports.
fix
Use a named import specifically: `import { parse } from 'unbash';` (and similarly for `print` from `unbash/print`).
My parsed and then printed script looks different from the original input; comments and exact whitespace are gone.
The `print` function is an opinionated code formatter. It intentionally re-formats the AST into a standardized Bash script string and does not preserve original non-semantic elements.
fix
This is expected behavior. The purpose of `print` is to produce a well-formatted, functional Bash script from the AST, not to recreate the input verbatim. If exact formatting preservation is critical, `unbash`'s `print` might not be suitable for that specific task.
My program didn't report any errors even when I fed it a syntactically incorrect Bash script.
unbash implements tolerant parsing, meaning it collects syntax errors in the `errors` array within the returned AST object instead of throwing an exception.
fix
After every call to `parse()`, you must explicitly check the `ast.errors` property. For example: `const ast = parse(script); if (ast.errors && ast.errors.length > 0) { console.error('Parsing failed:', ast.errors); }`
Upgrade
Version history
2.2.0latest on npm
Audit
Dependencies

No dependency data recorded yet.

Agent activity
11 hits · last 30 days
node
8
OpenAI (training)
1
Resources