ECMAScript code generator that transforms Mozilla's Parser API ASTs back into executable JavaScript code
npx @tessl/cli install tessl/npm-escodegen@2.1.0Escodegen is an ECMAScript (JavaScript) code generator that transforms Mozilla's Parser API Abstract Syntax Trees (ASTs) back into executable JavaScript code. It provides the inverse operation to JavaScript parsers, enabling developers to programmatically generate JavaScript code from structured AST representations with full support for modern ECMAScript features, customizable formatting, and source map generation.
npm install escodegenconst escodegen = require("escodegen");ES6/ESM:
import * as escodegen from "escodegen";
import { generate } from "escodegen";const escodegen = require("escodegen");
// Generate code from an AST
const ast = {
type: 'BinaryExpression',
operator: '+',
left: { type: 'Literal', value: 40 },
right: { type: 'Literal', value: 2 }
};
const code = escodegen.generate(ast);
console.log(code); // "40 + 2"
// With formatting options
const minified = escodegen.generate(ast, {
format: escodegen.FORMAT_MINIFY
});
console.log(minified); // "40+2"Escodegen is built around several key components:
Main function for converting AST nodes to JavaScript code with extensive formatting and generation options.
/**
* Generate JavaScript code from an AST node
* @param {Object} node - Mozilla Parser API compatible AST node
* @param {Object} [options] - Code generation options
* @returns {string|Object} Generated JavaScript code or {code, map} object if sourceMapWithCode is true
*/
function generate(node, options);Re-exported function from estraverse for attaching comments to AST nodes.
/**
* Attach comments to AST nodes
* @param {Object} tree - AST tree
* @param {Array} comments - Array of comment objects
* @returns {Object} AST tree with attached comments
*/
function attachComments(tree, comments);Constants defining operator precedence levels for expression generation.
const Precedence = {
Sequence: 0,
Yield: 1,
Assignment: 1,
Conditional: 2,
ArrowFunction: 2,
Coalesce: 3,
LogicalOR: 4,
LogicalAND: 5,
BitwiseOR: 6,
BitwiseXOR: 7,
BitwiseAND: 8,
Equality: 9,
Relational: 10,
BitwiseSHIFT: 11,
Additive: 12,
Multiplicative: 13,
Exponentiation: 14,
Await: 15,
Unary: 15,
Postfix: 16,
Call: 17,
New: 18,
Member: 19,
Primary: 20
};Predefined formatting configurations for common code generation scenarios.
/**
* Minified format configuration
*/
const FORMAT_MINIFY = {
indent: {
style: '',
base: 0
},
renumber: true,
hexadecimal: true,
quotes: 'auto',
escapeless: true,
compact: true,
parentheses: false,
semicolons: false
};
/**
* Default format configuration
*/
const FORMAT_DEFAULTS = {
indent: {
style: ' ',
base: 0,
adjustMultilineComment: false
},
newline: '\n',
space: ' ',
json: false,
renumber: false,
hexadecimal: false,
quotes: 'single',
escapeless: false,
compact: false,
parentheses: true,
semicolons: true,
safeConcatenation: false,
preserveBlankLines: false
};Package version string for compatibility checking.
/**
* Package version string
* @type {string}
*/
const version;Browser environment detection flag.
/**
* Browser environment flag (false for Node.js)
* @type {boolean}
*/
const browser;The generate() function accepts an extensive options object for customizing code generation:
Complete options interface matching the structure from getDefaultOptions():
interface GenerationOptions {
/** Legacy indentation style (deprecated, use format.indent.style) */
indent?: string;
/** Legacy base indentation level (deprecated, use format.indent.base) */
base?: number | string;
/** Custom parser function */
parse?: Function;
/** Preserve comments */
comment?: boolean;
/** Format configuration object */
format?: {
/** Indentation configuration */
indent?: {
style?: string; // Indentation string (default: ' ')
base?: number; // Base indentation level (default: 0)
adjustMultilineComment?: boolean; // Adjust multiline comment indentation
};
/** Newline character sequence */
newline?: string;
/** Space character for formatting */
space?: string;
/** Generate JSON-compatible output */
json?: boolean;
/** Renumber variables for shorter names */
renumber?: boolean;
/** Use hexadecimal numbers when shorter */
hexadecimal?: boolean;
/** Quote style: 'single', 'double', 'auto' */
quotes?: string;
/** Avoid escaping characters when possible */
escapeless?: boolean;
/** Generate compact code without extra whitespace */
compact?: boolean;
/** Always use parentheses for precedence clarity */
parentheses?: boolean;
/** Always include semicolons */
semicolons?: boolean;
/** Prevent string concatenation issues */
safeConcatenation?: boolean;
/** Preserve blank lines from source */
preserveBlankLines?: boolean;
};
/** Mozilla-specific options */
moz?: {
comprehensionExpressionStartsWithAssignment?: boolean;
starlessGenerator?: boolean;
};
/** Source map file name */
sourceMap?: string;
/** Source map root path */
sourceMapRoot?: string;
/** Return both code and source map */
sourceMapWithCode?: boolean;
/** Include directive prologue */
directive?: boolean;
/** Preserve raw literal strings */
raw?: boolean;
/** Custom verbatim string property */
verbatim?: string;
/** Original source code for blank line preservation */
sourceCode?: string;
/** Original source content for source map */
sourceContent?: string;
/** File name for source map */
file?: string;
}Usage Examples:
const escodegen = require("escodegen");
const esprima = require("esprima");
// Parse JavaScript code
const code = "function hello() { return 'world'; }";
const ast = esprima.parseScript(code);
// Generate with different formatting options
const standard = escodegen.generate(ast);
console.log(standard);
const minified = escodegen.generate(ast, {
format: escodegen.FORMAT_MINIFY
});
console.log(minified);
// Custom formatting
const custom = escodegen.generate(ast, {
format: {
indent: {
style: ' ', // 2-space indentation
base: 1
},
quotes: 'double',
semicolons: true
}
});
console.log(custom);
// With source maps
const withSourceMap = escodegen.generate(ast, {
sourceMap: 'output.js.map',
sourceMapWithCode: true
});
console.log(withSourceMap.code);
console.log(withSourceMap.map.toString());Escodegen provides two command-line tools for code generation:
Parses JavaScript files with esprima and regenerates them with escodegen.
escodegen [options] file...Options:
--config, -c: Configuration JSON file for escodegenBehavior:
comment: true is specified in configGenerates JavaScript code directly from JSON AST files.
esgenerate [options] file.json ...Options:
--config, -c: Configuration JSON file for escodegenBehavior:
Examples:
# Parse and regenerate JavaScript files
escodegen input.js output.js
# Generate code from JSON AST files
esgenerate ast.json syntax-tree.json
# Use custom configuration for comment preservation
echo '{"comment": true}' > config.json
escodegen --config config.json input.jsEscodegen supports browser environments through bundled distributions:
<script src="escodegen.browser.js"></script>
<script>
const ast = {
type: 'BinaryExpression',
operator: '+',
left: { type: 'Literal', value: 1 },
right: { type: 'Literal', value: 2 }
};
const code = escodegen.generate(ast);
console.log(code); // "1 + 2"
</script>Escodegen may throw errors in the following situations:
try {
const invalidAst = { type: 'InvalidNode' };
const code = escodegen.generate(invalidAst);
} catch (error) {
console.error('Code generation failed:', error.message);
}