or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

eslint-scope.mdeslint-visitor-keys.mdespree.mdindex.md
tile.json

espree.mddocs/

Espree

Espree is an Esprima-compatible JavaScript parser built on Acorn that parses JavaScript code into Abstract Syntax Trees (AST) following the ESTree specification. It provides parsing and tokenization capabilities with support for modern ECMAScript features through ECMAScript 2025 and partial ECMAScript 2026 support.

Core Imports

import * as espree from "espree";

For CommonJS:

const espree = require("espree");

Named imports (ESM):

import { parse, tokenize, version, VisitorKeys, Syntax, latestEcmaVersion, supportedEcmaVersions } from "espree";

Basic Usage

import * as espree from "espree";

// Parse JavaScript code into AST
const ast = espree.parse('let foo = "bar"', { 
  ecmaVersion: 2022,
  sourceType: "module" 
});

// Tokenize JavaScript code
const tokens = espree.tokenize('let foo = "bar"', { 
  ecmaVersion: 2022 
});

// Check supported ECMAScript versions
console.log(espree.supportedEcmaVersions); // [3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]
console.log(espree.latestEcmaVersion); // 17

Capabilities

JavaScript Parsing

Parses JavaScript code and returns an Abstract Syntax Tree (AST).

/**
 * Parses JavaScript code and returns an Abstract Syntax Tree (AST)
 * @param {string} code - The JavaScript code to parse
 * @param {ParserOptions} options - Parser configuration options
 * @returns {Program} The "Program" AST node
 * @throws {SyntaxError} If the input code is invalid
 */
function parse(code, options);

JavaScript Tokenization

Tokenizes JavaScript code and returns an array of tokens.

/**
 * Tokenizes JavaScript code and returns an array of tokens
 * @param {string} code - The JavaScript code to tokenize
 * @param {ParserOptions} options - Parser configuration options (tokens forced to true)
 * @returns {Token[]} Array of token objects
 * @throws {SyntaxError} If the input code is invalid
 */
function tokenize(code, options);

ECMAScript Version Constants

Constants providing information about supported ECMAScript versions.

/**
 * Latest ECMAScript version supported by espree
 * @type {number} Latest supported ECMAScript version (17 for ES2026)
 */
const latestEcmaVersion: number;

/**
 * Array of all supported ECMAScript versions
 * @type {number[]} Array of supported versions: [3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]
 */
const supportedEcmaVersions: number[];

Package Metadata

Package version and identification constants.

/** Current espree version string */
const version: string;

/** Package name ("espree") */
const name: string;

AST Utilities

Utilities for working with Abstract Syntax Trees.

/** 
 * AST visitor keys from eslint-visitor-keys for tree traversal
 * Contains property names that hold child nodes for each AST node type
 */
const VisitorKeys: object;

/** 
 * AST node type constants derived from VisitorKeys
 * Object with AST node type names as both keys and values
 */
const Syntax: object;

Parser Options

interface ParserOptions {
  /** ECMAScript version: 3, 5, 6-17, 2015-2026, or "latest" */
  ecmaVersion?: number | "latest";
  
  /** Source type: "script", "module", or "commonjs" */
  sourceType?: "script" | "module" | "commonjs";
  
  /** Attach range information to each node */
  range?: boolean;
  
  /** Attach line/column location information to each node */
  loc?: boolean;
  
  /** Create a top-level comments array containing all comments */
  comment?: boolean;
  
  /** Create a top-level tokens array containing all tokens */
  tokens?: boolean;
  
  /** Allow reserved words (only allowed when ecmaVersion is 3) */
  allowReserved?: boolean;
  
  /** Additional language features */
  ecmaFeatures?: ECMAFeatures;
}

interface ECMAFeatures {
  /** Enable JSX parsing */
  jsx?: boolean;
  
  /** Allow return statement in global scope (automatically true for sourceType "commonjs") */
  globalReturn?: boolean;
  
  /** Enable implied strict mode (if ecmaVersion >= 5) */
  impliedStrict?: boolean;
}

AST and Token Types

interface Program {
  type: "Program";
  body: Statement[];
  sourceType: "script" | "module";
  start?: number;
  end?: number;
  range?: [number, number];
  loc?: SourceLocation;
  comments?: Comment[];
  tokens?: Token[];
}

interface Token {
  type: string; // "Keyword", "Identifier", "Punctuator", "String", "Numeric", etc.
  value: string;
  start: number;
  end: number;
  range?: [number, number];
  loc?: SourceLocation;
}

interface SourceLocation {
  start: Position;
  end: Position;
}

interface Position {
  line: number; // 1-based
  column: number; // 0-based
}

interface Comment {
  type: "Line" | "Block";
  value: string;
  start: number;
  end: number;
  range?: [number, number];
  loc?: SourceLocation;
}

Usage Examples

Parsing with different ECMAScript versions:

import * as espree from "espree";

// ES5 parsing
const es5Ast = espree.parse("var x = 5;", { ecmaVersion: 5 });

// ES2020 parsing with optional chaining
const es2020Ast = espree.parse("obj?.prop?.method?.()", { ecmaVersion: 11 });

// Latest ECMAScript features
const latestAst = espree.parse("const x = 5;", { ecmaVersion: "latest" });

Module vs Script parsing:

// Parse as ES module
const moduleAst = espree.parse("import { foo } from 'bar';", {
  ecmaVersion: 2022,
  sourceType: "module"
});

// Parse as script
const scriptAst = espree.parse("var foo = require('bar');", {
  ecmaVersion: 2022,
  sourceType: "script"
});

// Parse as CommonJS
const commonjsAst = espree.parse("return module.exports;", {
  ecmaVersion: 2022,
  sourceType: "commonjs"
});

JSX parsing:

const jsxAst = espree.parse("const element = <div>Hello</div>;", {
  ecmaVersion: 2022,
  sourceType: "module",
  ecmaFeatures: {
    jsx: true
  }
});

Tokenization with location information:

const tokens = espree.tokenize('let x = "hello";', {
  ecmaVersion: 2022,
  loc: true,
  range: true
});

console.log(tokens);
// [
//   { type: 'Keyword', value: 'let', start: 0, end: 3, loc: {...} },
//   { type: 'Identifier', value: 'x', start: 4, end: 5, loc: {...} },
//   { type: 'Punctuator', value: '=', start: 6, end: 7, loc: {...} },
//   { type: 'String', value: '"hello"', start: 8, end: 15, loc: {...} }
// ]

Parsing with comments and tokens:

const ast = espree.parse(`
  // This is a comment
  let x = 42; /* Another comment */
`, {
  ecmaVersion: 2022,
  comment: true,
  tokens: true,
  loc: true
});

console.log(ast.comments.length); // 2
console.log(ast.tokens.length); // 4 (let, x, =, 42)

Error handling:

try {
  const ast = espree.parse("let x = ;", { ecmaVersion: 2022 });
} catch (error) {
  if (error instanceof SyntaxError) {
    console.log("Parsing error:", error.message);
    console.log("Line:", error.lineNumber);
    console.log("Column:", error.column);
    console.log("Index:", error.index);
  }
}

Working with visitor keys and syntax:

import * as espree from "espree";

const ast = espree.parse("function test() { return 42; }", { ecmaVersion: 2022 });

// Access visitor keys
console.log(espree.VisitorKeys.FunctionDeclaration); // ["id", "params", "body"]

// Use syntax constants
console.log(espree.Syntax.FunctionDeclaration); // "FunctionDeclaration"

// Traverse AST using visitor keys
function traverse(node, visitor) {
  if (typeof visitor[node.type] === "function") {
    visitor[node.type](node);
  }
  
  const keys = espree.VisitorKeys[node.type] || [];
  for (const key of keys) {
    const child = node[key];
    if (Array.isArray(child)) {
      for (const item of child) {
        if (item && typeof item === "object") {
          traverse(item, visitor);
        }
      }
    } else if (child && typeof child === "object") {
      traverse(child, visitor);
    }
  }
}

traverse(ast, {
  FunctionDeclaration(node) {
    console.log(`Found function: ${node.id.name}`);
  }
});

ECMAScript Support

  • Full support: ES3, ES5, ES2015-ES2025 (versions 3, 5, 6-16)
  • Partial support: ES2026 (version 17) - includes Explicit Resource Management
  • JSX support: Available via acorn-jsx plugin when ecmaFeatures.jsx is enabled
  • Version mapping:
    • Year-based: 2015→6, 2016→7, 2017→8, 2018→9, 2019→10, 2020→11, 2021→12, 2022→13, 2023→14, 2024→15, 2025→16, 2026→17
    • Use "latest" for the most recent supported version

Supported ECMAScript Features by Version

ES6/ES2015 (version 6):

  • Arrow functions, classes, modules, destructuring, template literals, let/const

ES2017 (version 8):

  • Async/await, object spread properties

ES2018 (version 9):

  • Object rest/spread, async iteration, regular expression improvements

ES2019 (version 10):

  • Optional catch binding, Array.flat(), Object.fromEntries()

ES2020 (version 11):

  • Optional chaining (?.), nullish coalescing (??), BigInt, dynamic imports

ES2021 (version 12):

  • Logical assignment operators (||=, &&=, ??=), numeric separators

ES2022 (version 13):

  • Private class methods and fields, static class blocks, top-level await

ES2023 (version 14):

  • Array findLast(), hashbang comments

ES2024 (version 15):

  • Array grouping methods, Atomics.waitAsync()

ES2025 (version 16):

  • Pattern matching (proposal stage)

ES2026 (version 17) - Partial:

  • Explicit Resource Management (using, await using)

Error Handling

Espree throws SyntaxError for invalid JavaScript code with detailed error information:

// Enhanced SyntaxError properties
interface EspreeSyntaxError extends SyntaxError {
  message: string;      // Descriptive error message
  lineNumber: number;   // 1-based line number
  column: number;       // 0-based column number  
  index: number;        // 0-based character index
}

Common validation errors:

  • Invalid ecmaVersion values
  • Invalid sourceType values
  • Invalid ecmaFeatures combinations
  • sourceType: "module" with ecmaVersion < 6
  • allowReserved used with ecmaVersion !== 3

Error handling examples:

// Invalid syntax
try {
  espree.parse("let x = ;", { ecmaVersion: 2022 });
} catch (error) {
  console.log(error.message); // "Unexpected token ;"
  console.log(error.lineNumber); // 1
  console.log(error.column); // 8
}

// Invalid options
try {
  espree.parse("const x = 1;", { 
    ecmaVersion: 5, // const not supported in ES5
    sourceType: "script" 
  });
} catch (error) {
  console.log(error.message); // "Unexpected token const"
}

// Module syntax with wrong sourceType
try {
  espree.parse("import x from 'y';", { 
    ecmaVersion: 2022,
    sourceType: "script" // Should be "module"
  });
} catch (error) {
  console.log(error.message); // "'import' and 'export' may appear only with 'sourceType: module'"
}

Performance Considerations

  • Parser caching: Espree caches parser instances for better performance
  • Memory usage: AST nodes can be large; consider using streaming for very large files
  • Token generation: Only enable tokens: true when needed, as it increases memory usage
  • Location tracking: loc and range options add overhead but are useful for error reporting
  • Comment attachment: comment: true and attachComments: true add processing overhead

Integration with Tools

Espree integrates seamlessly with JavaScript tooling:

ESLint integration:

// ESLint uses espree as its default parser
module.exports = {
  parser: "espree", // Default parser
  parserOptions: {
    ecmaVersion: 2022,
    sourceType: "module",
    ecmaFeatures: {
      jsx: true
    }
  }
};

Custom AST processing:

import * as espree from "espree";

class CodeAnalyzer {
  analyze(code, options = {}) {
    const ast = espree.parse(code, {
      ecmaVersion: "latest",
      sourceType: "module",
      loc: true,
      ...options
    });
    
    return this.processAST(ast);
  }
  
  processAST(ast) {
    // Custom analysis logic
    return {
      functions: this.findFunctions(ast),
      variables: this.findVariables(ast),
      imports: this.findImports(ast)
    };
  }
}