Library / SDK
acornjs/acorn avatar
acornjs/acorn

Acorn: A Small, Plugin-Ready JavaScript Parser with Three Companion Packages

A small, fast, JavaScript-based JavaScript parser

11,451 stars1,051 forksJavaScriptLicense varies

At a glance

What is it?
Acorn is a JavaScript parser written entirely in JavaScript, available through the acornjs/acorn repository as three coordinated packages. The main acorn package produces a standard AST, acorn-loose tolerates syntax errors and still produces a tree, and acorn-walk traverses those trees. A plugin system allows language extensions without forking, at the cost of coupling plugins to Acorn's internal class structure.
Who is it for?
JavaScript toolchain developers who need to extend ECMAScript syntax for a custom dialect, without maintaining a full parser fork, are the right candidates for Acorn's plugin API. Plugins interact with Acorn's internals directly, so teams must pin an exact Acorn version and test plugins after each Acorn update.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What Acorn Is and the Problem It Targets

Acorn parses JavaScript source text and produces an AST in the ESTree specification format. Its value proposition is size and composability: it is written in JavaScript, carries no native binary dependencies, and ships to npm with a minimal footprint. This makes it a suitable foundation for linters, code analysis tools, bundlers, and transpilers that need to parse JavaScript as a step in a larger pipeline.

The repository at acornjs/acorn bundles three separate packages under one workspace. Each serves a distinct role in the same pipeline. Most users of downstream tools never interact with Acorn directly, but a significant portion of the JavaScript build tooling ecosystem depends on it as a parsing substrate. The maintainers listed in the root package.json are Marijn Haverbeke, Ingvar Stepanyan, and Adrian Heine.

Three Packages: acorn, acorn-loose, and acorn-walk

The acorn package is the main parser. It takes JavaScript source text and returns an AST. The acorn-loose package is an error-tolerant variant that can parse code with syntax errors and still produce a usable tree, which is useful in editors and tooling that must handle partially written code. The acorn-walk package provides utilities for traversing the AST that either of the two parsers produces.

The packages are built separately but share the same workspace. The root README points to each sub-directory for package-specific documentation. Building all three requires running npm install from the repository root, which triggers the build for each package through the configured npm scripts.

The npm badge in the README links to the acorn package on npm. The cdnjs badge links to a browser-friendly distribution. Neither the README nor the package.json documents which Node.js or browser versions are supported, so consumers who need a specific minimum runtime version need to test it directly.

Installing and Building Acorn from the Repository

To build the repository and run the test suite, clone it and run npm install from the root:

sh
git clone https://github.com/acornjs/acorn.git
cd acorn
npm install

The npm install step triggers a pretest script that builds the main parser and the loose parser before the tests run. The test suite at test/run.js exercises the main package. A separate test runner at bin/run_test262.js checks conformance against the TC39 test262 suite, which covers the full ECMAScript specification test corpus.

The scripts in package.json also include build targets for each package individually (build:main, build:walk, build:loose), a lint step using ESLint, and a code generation step that regenerates the identifier regex and unicode script values from source data. Contributors working on Unicode support or identifier parsing would use those generation scripts.

The library is published to npm as the acorn package. Downstream projects add it as a dependency in the usual way and import the Parser class directly without needing to build from source.

The Plugin System: How It Works and Where It Breaks

Acorn's plugin system is based on class extension. A plugin is a function that takes a parser class as input and returns an extended class. The Parser.extend static method accepts one or more plugin functions and returns a new class that combines all their extensions. The README recommends creating the extended class once and reusing it for all parse calls to avoid confusing the JavaScript engine's optimizer.

javascript
const {Parser} = require("acorn")

const MyParser = Parser.extend(
  require("acorn-jsx")(),
  require("acorn-bigint")
)
console.log(MyParser.parse("// Some bigint + JSX code"))

A plugin overrides methods in the extended class. The README gives a minimal example of a plugin that overrides the readToken method:

javascript
module.exports = function noisyReadToken(Parser) {
  return class extends Parser {
    readToken(code) {
      console.log("Reading a token!")
      super.readToken(code)
    }
  }
}

The README is explicit about the cost: plugins require understanding Acorn's internals, and they are likely to break whenever those internals change significantly. The plugin API is not separately versioned from Acorn's internal structure. This is a design trade-off: the system allows custom language dialects without forking, but it does not provide a stable, documented extension boundary. Plugin maintainers must track Acorn's internals and update after each release that touches the methods their plugin overrides.

Testing Against the ECMAScript Test262 Suite

The devDependencies in package.json include test262 as a git dependency pinned to a specific commit, along with test262-parser-runner. The test runner at bin/run_test262.js exercises Acorn against the full specification test corpus. This is a meaningful signal about specification conformance: it means the maintainers track which test262 cases pass and which ones do not.

The build pipeline also includes generated source files. bin/generate-identifier-regex.js regenerates the regex that Acorn uses to identify valid JavaScript identifiers, and bin/generate-unicode-script-values.js regenerates the Unicode script value tables. Both depend on the @unicode/unicode-18.0.0 devDependency, which means the repository is targeting Unicode 18.0.0 for identifier and script data. Running npm run generate updates these files when a new Unicode release occurs.

The last push to the repository was on 2026-09-27, one day before this writing. The repository is not archived.

When to Fork Rather Than Use a Plugin

The plugin system makes sense for extensions that add new token types, new tokenizer contexts, or method overrides to handle new syntax. If two plugins override the same internal method and neither calls super correctly, they will conflict silently. The README acknowledges this: it says combining plugins is possible in principle, but does not document how to resolve conflicts when two plugins need to modify the same method.

For a dialect that requires deep structural changes to how the parser handles statements or expressions, the plugin API becomes fragile. Each significant Acorn internal refactor will break the plugin. At that point, maintaining a fork of Acorn with the changes merged in directly is sometimes less work than adapting a plugin to each release, because a fork can absorb changes in one place rather than chasing internal method renames across plugin code.

The acorn-loose package illustrates the boundary: its error recovery is implemented as a separate package that shares some Acorn internals, not as a plugin. More invasive changes to parsing behavior follow that same pattern in the official repository.

Editorial conclusion

JavaScript toolchain developers who need to extend ECMAScript syntax for a custom dialect, without maintaining a full parser fork, are the right candidates for Acorn's plugin API. Plugins interact with Acorn's internals directly, so teams must pin an exact Acorn version and test plugins after each Acorn update. Developers who only need AST output without any language extension can use the acorn package as a zero-configuration parser, building the repo and running it directly from npm. Confirm that acorn-loose fits the error-recovery behavior the project needs, since the README does not specify which recovery strategies it uses.

Frequently asked questions

What are the three packages in the Acorn repository?

The repository holds acorn (the main JavaScript parser), acorn-loose (an error-tolerant parser that produces an AST even from code with syntax errors), and acorn-walk (a utility for traversing the AST produced by either parser).

Does Acorn parse JSX out of the box?

No. The README example shows that JSX parsing requires the acorn-jsx plugin, which is applied using Parser.extend before calling parse.

Are Acorn plugins guaranteed to stay compatible across Acorn releases?

No. The README explicitly states that plugins are likely to break whenever Acorn's internals change significantly, because the plugin API requires understanding and overriding internal methods directly.

Official sources

  1. acornjs/acorn on GitHub
  2. Issues
  3. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/acornjs-acorn.svg)](https://hysenlabs.com/projects/acornjs-acorn)