or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

acorn-loose.mdacorn-walk.mdacorn.mdindex.md
tile.json

acorn.mddocs/

Acorn Core Parser

The main Acorn parser provides fast, standards-compliant ECMAScript parsing with full support for ES2025 features and an extensible plugin architecture. It generates ESTree-compatible Abstract Syntax Trees (ASTs) from JavaScript source code.

Core Imports

import { parse, parseExpressionAt, tokenizer, Parser, defaultOptions } from "acorn";

For CommonJS:

const { parse, parseExpressionAt, tokenizer, Parser, defaultOptions } = require("acorn");

Capabilities

Main Parse Function

Parses a complete JavaScript program or module into an AST.

/**
 * Parses JavaScript source code into an ESTree-compatible AST
 * @param input - JavaScript source code string
 * @param options - Parser configuration options
 * @returns Program node representing the parsed code
 */
function parse(input: string, options: Options): Program;

Usage Example:

import { parse } from "acorn";

const code = `
  function greet(name) {
    console.log("Hello, " + name + "!");
  }
  
  greet("World");
`;

const ast = parse(code, {
  ecmaVersion: 2020,
  sourceType: "script"
});

console.log(ast.type); // "Program"
console.log(ast.body.length); // 2 (function declaration + expression statement)

Expression Parsing

Parses a single expression at a specific position in the source code.

/**
 * Parses a single expression at the given position
 * @param input - JavaScript source code string
 * @param pos - Character offset to start parsing from
 * @param options - Parser configuration options
 * @returns Expression node
 */
function parseExpressionAt(input: string, pos: number, options: Options): Expression;

Usage Example:

import { parseExpressionAt } from "acorn";

const code = "let x = 42 + 8;";
const expr = parseExpressionAt(code, 8, { ecmaVersion: 2020 }); // Parse "42 + 8"

console.log(expr.type); // "BinaryExpression"
console.log(expr.operator); // "+"

Tokenizer

Creates a tokenizer that can iterate through all tokens in the source code.

/**
 * Creates a tokenizer for the given input
 * @param input - JavaScript source code string
 * @param options - Parser configuration options
 * @returns Tokenizer object with getToken() method and iterator support
 */
function tokenizer(input: string, options: Options): {
  getToken(): Token;
  [Symbol.iterator](): Iterator<Token>;
};

Usage Example:

import { tokenizer } from "acorn";

const code = "let x = 42;";
const tokens = tokenizer(code, { ecmaVersion: 2020 });

// Using iterator
for (const token of tokens) {
  console.log(`${token.type.label}: ${token.start}-${token.end}`);
}

// Using getToken() method
const tokenizer2 = tokenizer(code, { ecmaVersion: 2020 });
let token;
while ((token = tokenizer2.getToken()).type !== tokTypes.eof) {
  console.log(token);
}

Parser Class

The main Parser class with static methods and plugin support.

/**
 * Main Parser class with static parsing methods and plugin extension support
 */
class Parser {
  options: Options;
  input: string;
  
  protected constructor(options: Options, input: string, startPos?: number);
  
  /**
   * Parse a complete program
   */
  parse(): Program;
  
  /**
   * Static method to parse input with options
   */
  static parse(input: string, options: Options): Program;
  
  /**
   * Static method to parse expression at position
   */
  static parseExpressionAt(input: string, pos: number, options: Options): Expression;
  
  /**
   * Static method to create tokenizer
   */
  static tokenizer(input: string, options: Options): {
    getToken(): Token;
    [Symbol.iterator](): Iterator<Token>;
  };
  
  /**
   * Extend parser with plugins
   */
  static extend(...plugins: ((BaseParser: typeof Parser) => typeof Parser)[]): typeof Parser;
}

Plugin Usage Example:

import { Parser } from "acorn";

// Example plugin for JSX-like syntax
function jsxPlugin(BaseParser) {
  return class extends BaseParser {
    parseExprAtom() {
      if (this.type === tt.lt && this.input.charCodeAt(this.pos) !== 47) {
        return this.parseJSXElement();
      }
      return super.parseExprAtom();
    }
    
    parseJSXElement() {
      // Custom JSX parsing logic
      const node = this.startNode();
      // ... implementation
      return this.finishNode(node, "JSXElement");
    }
  };
}

const JSXParser = Parser.extend(jsxPlugin);
const ast = JSXParser.parse("<div>Hello</div>", { ecmaVersion: 2020 });

Parser Options

Comprehensive configuration options for controlling parser behavior.

interface Options {
  /**
   * ECMAScript version to parse. Can be a number (3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)
   * or year (2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025)
   * or "latest" for the latest supported version
   */
  ecmaVersion: ecmaVersion;
  
  /**
   * Source type: "script" or "module"
   * Affects global strict mode and import/export parsing
   */
  sourceType?: "script" | "module";
  
  /**
   * Callback for automatic semicolon insertion events
   */
  onInsertedSemicolon?: (lastTokEnd: number, lastTokEndLoc?: Position) => void;
  
  /**
   * Callback for trailing comma events
   */
  onTrailingComma?: (lastTokEnd: number, lastTokEndLoc?: Position) => void;
  
  /**
   * Control reserved word enforcement
   * true/false or "never" to disallow as property names too
   */
  allowReserved?: boolean | "never";
  
  /**
   * Allow return statements at top level
   */
  allowReturnOutsideFunction?: boolean;
  
  /**
   * Allow import/export anywhere in the program
   */
  allowImportExportEverywhere?: boolean;
  
  /**
   * Allow await identifiers at top level
   */
  allowAwaitOutsideFunction?: boolean;
  
  /**
   * Allow super identifiers outside methods
   */
  allowSuperOutsideMethod?: boolean;
  
  /**
   * Allow hashbang directive (#!) at start of file
   */
  allowHashBang?: boolean;
  
  /**
   * Validate private field usage
   */
  checkPrivateFields?: boolean;
  
  /**
   * Include location information in nodes
   */
  locations?: boolean;
  
  /**
   * Token callback or array to collect tokens
   */
  onToken?: ((token: Token) => void) | Token[];
  
  /**
   * Comment callback or array to collect comments
   */
  onComment?: ((
    isBlock: boolean, text: string, start: number, end: number, 
    startLoc?: Position, endLoc?: Position
  ) => void) | Comment[];
  
  /**
   * Include range information as [start, end] arrays
   */
  ranges?: boolean;
  
  /**
   * Existing program node to extend (for parsing multiple files)
   */
  program?: Node;
  
  /**
   * Source file name for location info
   */
  sourceFile?: string;
  
  /**
   * Direct source file for all nodes
   */
  directSourceFile?: string;
  
  /**
   * Preserve parenthesized expressions as ParenthesizedExpression nodes
   */
  preserveParens?: boolean;
}

type ecmaVersion = 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 
                 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 
                 | "latest";

Default Options

Pre-configured default options for the parser.

/**
 * Default parser options
 */
const defaultOptions: Options;

Utility Functions

Helper functions for working with parsed code.

/**
 * Get line/column information for a character offset
 * @param input - Source code string
 * @param offset - Character offset
 * @returns Position with line and column numbers
 */
function getLineInfo(input: string, offset: number): Position;

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

interface SourceLocation {
  source?: string | null;
  start: Position;
  end: Position;
}

Token System

Token types and token objects returned by the tokenizer.

/**
 * Token type definitions
 */
class TokenType {
  label: string;
  keyword: string | undefined;
}

/**
 * All available token types
 */
const tokTypes: {
  // Literals and identifiers
  num: TokenType;
  regexp: TokenType;
  string: TokenType;
  name: TokenType;
  privateId: TokenType;
  eof: TokenType;
  
  // Punctuation
  bracketL: TokenType;  // [
  bracketR: TokenType;  // ]
  braceL: TokenType;    // {
  braceR: TokenType;    // }
  parenL: TokenType;    // (
  parenR: TokenType;    // )
  comma: TokenType;     // ,
  semi: TokenType;      // ;
  colon: TokenType;     // :
  dot: TokenType;       // .
  question: TokenType;  // ?
  questionDot: TokenType; // ?.
  arrow: TokenType;     // =>
  ellipsis: TokenType;  // ...
  backQuote: TokenType; // `
  dollarBraceL: TokenType; // ${
  
  // Operators
  eq: TokenType;        // ==, ===, !=, !==
  assign: TokenType;    // =, +=, -=, etc.
  incDec: TokenType;    // ++, --
  prefix: TokenType;    // !, ~, -, +
  logicalOR: TokenType; // ||
  logicalAND: TokenType; // &&
  bitwiseOR: TokenType; // |
  bitwiseXOR: TokenType; // ^
  bitwiseAND: TokenType; // &
  equality: TokenType;  // ==, !=, ===, !==
  relational: TokenType; // <, >, <=, >=, in, instanceof
  bitShift: TokenType;  // <<, >>, >>>
  plusMin: TokenType;   // +, -
  modulo: TokenType;    // %
  star: TokenType;      // *
  slash: TokenType;     // /
  starstar: TokenType;  // **
  coalesce: TokenType;  // ??
  
  // Keywords
  _break: TokenType;
  _case: TokenType;
  _catch: TokenType;
  _continue: TokenType;
  _debugger: TokenType;
  _default: TokenType;
  _do: TokenType;
  _else: TokenType;
  _finally: TokenType;
  _for: TokenType;
  _function: TokenType;
  _if: TokenType;
  _return: TokenType;
  _switch: TokenType;
  _throw: TokenType;
  _try: TokenType;
  _var: TokenType;
  _const: TokenType;
  _while: TokenType;
  _with: TokenType;
  _new: TokenType;
  _this: TokenType;
  _super: TokenType;
  _class: TokenType;
  _extends: TokenType;
  _export: TokenType;
  _import: TokenType;
  _null: TokenType;
  _true: TokenType;
  _false: TokenType;
  _in: TokenType;
  _instanceof: TokenType;
  _typeof: TokenType;
  _void: TokenType;
  _delete: TokenType;
};

/**
 * Token object returned by tokenizer
 */
class Token {
  type: TokenType;
  start: number;
  end: number;
  loc?: SourceLocation;
  range?: [number, number];
}

/**
 * Comment object when using onComment option
 */
interface Comment {
  type: "Line" | "Block";
  value: string;
  start: number;
  end: number;
  loc?: SourceLocation;
  range?: [number, number];
}

AST Node Types

Complete type definitions for all ESTree-compatible AST nodes.

// Base node interface
interface Node {
  start: number;
  end: number;
  type: string;
  range?: [number, number];
  loc?: SourceLocation | null;
}

// Program node (root)
interface Program extends Node {
  type: "Program";
  body: Array<Statement | ModuleDeclaration>;
  sourceType: "script" | "module";
}

// Statements
type Statement = 
  | ExpressionStatement
  | BlockStatement
  | EmptyStatement
  | DebuggerStatement
  | WithStatement
  | ReturnStatement
  | LabeledStatement
  | BreakStatement
  | ContinueStatement
  | IfStatement
  | SwitchStatement
  | ThrowStatement
  | TryStatement
  | WhileStatement
  | DoWhileStatement
  | ForStatement
  | ForInStatement
  | ForOfStatement
  | Declaration;

// Expressions
type Expression = 
  | Identifier
  | Literal
  | ThisExpression
  | ArrayExpression
  | ObjectExpression
  | FunctionExpression
  | UnaryExpression
  | UpdateExpression
  | BinaryExpression
  | AssignmentExpression
  | LogicalExpression
  | MemberExpression
  | ConditionalExpression
  | CallExpression
  | NewExpression
  | SequenceExpression
  | ArrowFunctionExpression
  | YieldExpression
  | TemplateLiteral
  | TaggedTemplateExpression
  | ClassExpression
  | MetaProperty
  | AwaitExpression
  | ChainExpression
  | ImportExpression
  | ParenthesizedExpression;

// Declarations
type Declaration = 
  | FunctionDeclaration
  | VariableDeclaration
  | ClassDeclaration;

// Module declarations
type ModuleDeclaration = 
  | ImportDeclaration
  | ExportNamedDeclaration
  | ExportDefaultDeclaration
  | ExportAllDeclaration;

// Patterns
type Pattern = 
  | Identifier
  | MemberExpression
  | ObjectPattern
  | ArrayPattern
  | RestElement
  | AssignmentPattern;

Common Usage Patterns

Basic Parsing with Options

import { parse } from "acorn";

const options = {
  ecmaVersion: 2022,
  sourceType: "module",
  locations: true,
  ranges: true
};

const ast = parse(`
  import { helper } from './utils.js';
  
  export default function main() {
    const data = await helper();
    return data?.results ?? [];
  }
`, options);

console.log(ast.sourceType); // "module"
console.log(ast.body[0].type); // "ImportDeclaration"

Token Collection

import { parse } from "acorn";

const tokens = [];
const ast = parse(`let x = 42;`, {
  ecmaVersion: 2020,
  onToken: token => tokens.push(token)
});

tokens.forEach(token => {
  console.log(`${token.type.label}: "${token.start}-${token.end}"`);
});

Comment Preservation

import { parse } from "acorn";

const comments = [];
const ast = parse(`
  // This is a line comment
  function example() {
    /* Block comment */
    return true;
  }
`, {
  ecmaVersion: 2020,
  onComment: comments
});

comments.forEach(comment => {
  console.log(`${comment.type}: ${comment.value}`);
});

Error Handling

import { parse } from "acorn";

try {
  const ast = parse("let x = ;", { ecmaVersion: 2020 });
} catch (error) {
  console.log(`Parse error at position ${error.pos}: ${error.message}`);
  // For error recovery, use acorn-loose instead
}