Esprima is a high-performance, standard-compliant ECMAScript parser written in TypeScript that provides comprehensive JavaScript parsing capabilities. It offers full support for ECMAScript 2017 (ECMA-262 8th Edition), follows the ESTree syntax tree format standard, and includes experimental JSX support for React development. The library enables both lexical analysis (tokenization) and syntactic analysis (parsing) of JavaScript programs, with optional syntax node location tracking and extensive testing coverage.
npm install esprimaimport * as esprima from "esprima";
// or specific imports
import { parse, parseScript, parseModule, tokenize, Syntax } from "esprima";For CommonJS:
const esprima = require("esprima");
// or specific imports
const { parse, parseScript, parseModule, tokenize, Syntax } = require("esprima");import { parse, parseScript, tokenize } from "esprima";
// Parse JavaScript code into an AST
const ast = parse("const answer = 42;");
console.log(ast.body[0].type); // "VariableDeclaration"
// Parse as a script with options
const scriptAst = parseScript("function greet() { return 'Hello'; }", {
range: true,
loc: true,
tokens: true
});
// Tokenize JavaScript code
const tokens = tokenize("x = 1 + 2");
console.log(tokens);
// [
// { type: 'Identifier', value: 'x' },
// { type: 'Punctuator', value: '=' },
// { type: 'Numeric', value: '1' },
// { type: 'Punctuator', value: '+' },
// { type: 'Numeric', value: '2' }
// ]Esprima is built around several key components:
Esprima includes command-line utilities for parsing and validating JavaScript files from the terminal.
# ESParse - Parse JavaScript and output AST as JSON
esparse [options] [file.js]
# ESValidate - Validate JavaScript syntax
esvalidate [options] [file.js...]After installing esprima globally (npm install -g esprima), these tools become available:
ESParse Usage:
# Parse a file and output AST
esparse script.js
# Parse with additional options
esparse --tokens --loc --range script.js
# Parse from stdin
cat script.js | esparse
# Available options:
# --comment Gather all line and block comments
# --loc Include line-column location info
# --range Include index-based range info
# --raw Display raw value of literals
# --tokens List all tokens in an array
# --tolerant Tolerate errors on best-effort basisESValidate Usage:
# Validate single file
esvalidate script.js
# Validate multiple files
esvalidate src/*.js
# Output in JUnit format
esvalidate --format=junit test.js
# Available options:
# --format=type Set report format (plain or junit)Core parsing functionality that converts JavaScript source code into Abstract Syntax Trees (AST) following the ESTree specification.
function parse(code: string, options?: ParseOptions, delegate?: NodeVisitor): Program;
function parseScript(code: string, options?: ParseOptions, delegate?: NodeVisitor): Program;
function parseModule(code: string, options?: ParseOptions, delegate?: NodeVisitor): Program;
interface ParseOptions {
range?: boolean;
loc?: boolean;
source?: string;
tokens?: boolean;
comment?: boolean;
attachComment?: boolean;
tolerant?: boolean;
jsx?: boolean;
sourceType?: 'script' | 'module';
}
interface Program {
type: 'Program';
body: Statement[];
sourceType: 'script' | 'module';
range?: [number, number];
loc?: SourceLocation;
comments?: Comment[];
tokens?: Token[];
errors?: ParseError[];
}Lexical analysis functionality that converts JavaScript source code into arrays of tokens for syntax highlighting, formatting, and analysis tools.
function tokenize(code: string, options?: TokenizeOptions, delegate?: TokenVisitor): Token[];
interface TokenizeOptions {
range?: boolean;
loc?: boolean;
comment?: boolean;
tolerant?: boolean;
}
interface Token {
type: string;
value: string;
range?: [number, number];
loc?: SourceLocation;
regex?: {
pattern: string;
flags: string;
};
}Extended parsing capabilities for JSX syntax used in React applications, enabling parsing of mixed JavaScript and JSX code.
// JSX parsing is enabled via options
const jsxAst = parse('<div>Hello {name}</div>', { jsx: true });
// JSX-specific AST node types
interface JSXElement {
type: 'JSXElement';
openingElement: JSXOpeningElement;
closingElement: JSXClosingElement | null;
children: JSXChild[];
}
interface JSXOpeningElement {
type: 'JSXOpeningElement';
name: JSXElementName;
attributes: JSXAttribute[];
selfClosing: boolean;
}interface SourceLocation {
start: Position;
end: Position;
source?: string;
}
interface Position {
line: number;
column: number;
}
interface Comment {
type: 'Line' | 'Block';
value: string;
range?: [number, number];
loc?: SourceLocation;
}
interface ParseError {
name: string;
message: string;
index: number;
lineNumber: number;
column: number;
description: string;
}
type NodeVisitor = (node: Node, metadata: any) => void;
type TokenVisitor = (token: Token) => Token | void;const Syntax: {
AssignmentExpression: 'AssignmentExpression';
ArrayExpression: 'ArrayExpression';
BlockStatement: 'BlockStatement';
BinaryExpression: 'BinaryExpression';
CallExpression: 'CallExpression';
ConditionalExpression: 'ConditionalExpression';
ExpressionStatement: 'ExpressionStatement';
FunctionDeclaration: 'FunctionDeclaration';
FunctionExpression: 'FunctionExpression';
Identifier: 'Identifier';
IfStatement: 'IfStatement';
Literal: 'Literal';
MemberExpression: 'MemberExpression';
NewExpression: 'NewExpression';
ObjectExpression: 'ObjectExpression';
Program: 'Program';
ReturnStatement: 'ReturnStatement';
ThisExpression: 'ThisExpression';
UnaryExpression: 'UnaryExpression';
UpdateExpression: 'UpdateExpression';
VariableDeclaration: 'VariableDeclaration';
VariableDeclarator: 'VariableDeclarator';
// ... and many more ESTree node types
};
const version: string; // Current version: "4.0.1"