# estree-toolkit

> Traverser, scope tracker, and more tools for working with ESTree AST

Latest version **1.7.14** (published 2026-05-03) · MIT license · 0 weekly downloads

## Install

```sh
npm install estree-toolkit
pnpm add estree-toolkit
yarn add estree-toolkit
bun add estree-toolkit
```

## Health

**Score 60/100 (C)** — status: active.

Positive: has types; esm support; no vulnerabilities; high quality score.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 1.7.14 |
| Published | 2026-05-03 |
| First published | 2021-01-11 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 2 |
| Unpacked size | 349.9 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 71 |
| Author | Sarsa Murmu |
| Maintainers | sarsamurmu |
| Keywords | estree, ast, traverse, scope, analysis, walker, visitor, binding, fast, acorn, meriyah |

## Links

- npm: https://www.npmjs.com/package/estree-toolkit
- Repository: https://github.com/sarsamurmu/estree-toolkit
- Homepage: https://estree-toolkit.netlify.app/
- Issues: https://github.com/sarsamurmu/estree-toolkit/issues
- npm.io page: https://npm.io/package/estree-toolkit

## Dependencies (2)

- [@types/estree](https://npm.io/package/@types/estree.md) >=1.0.8
- [@types/estree-jsx](https://npm.io/package/@types/estree-jsx.md) >=1.0.5

## Alternatives

- [update-check](https://npm.io/package/update-check.md) — 4.0M weekly downloads
- [react-native-onesignal](https://npm.io/package/react-native-onesignal.md) — 134.5K weekly downloads
- [react-redux-toastr](https://npm.io/package/react-redux-toastr.md) — 33.7K weekly downloads
- [@nocobase/plugin-notification-manager](https://npm.io/package/@nocobase/plugin-notification-manager.md) — 2.0K weekly downloads
- [react-simple-toasts](https://npm.io/package/react-simple-toasts.md) — 1.9K weekly downloads

## Recent versions

- 1.7.14 (latest) — 2026-05-03
- 1.7.13 — 2025-05-10
- 1.7.12 — 2025-04-02
- 1.7.11 — 2025-04-02
- 1.7.10 — 2025-03-31
- 1.7.9 — 2025-03-30
- 1.7.8 — 2024-09-10
- 1.7.7 — 2024-08-08
- 1.7.6 — 2024-07-25
- 1.7.5 — 2024-05-12
- 1.7.4 — 2024-05-11
- 1.7.3 — 2023-09-06
- 1.7.2 — 2023-08-14
- 1.7.1 — 2023-08-12
- 1.7.0 — 2023-08-11
- … 27 more at https://npm.io/package/estree-toolkit/versions

## README

<h1 align=center>
  <code>estree-toolkit</code>
</h1>
<h4 align=center>Tools for working with ESTree AST</h4>
<p align=center>
  <a href="https://npmjs.com/package/estree-toolkit">
    <img alt="npm" src="https://img.shields.io/npm/v/estree-toolkit?style=flat-square">
  </a>
  <a href="https://circleci.com/gh/sarsamurmu/estree-toolkit">
    <img alt="Circle CI" src="https://circleci.com/gh/sarsamurmu/estree-toolkit.svg?style=svg">
  </a>
  <a href="https://codecov.io/gh/sarsamurmu/estree-toolkit">
    <img alt="codecov" src="https://img.shields.io/codecov/c/github/sarsamurmu/estree-toolkit?style=flat-square">
  </a>
  <a href="https://github.com/sarsamurmu/estree-toolkit/blob/main/LICENSE">
    <img alt="License" src="https://img.shields.io/github/license/sarsamurmu/estree-toolkit?style=flat-square">
  </a>
</p>

## Installation
```bash
npm i estree-toolkit
# or
yarn add estree-toolkit
```

## Usage
```js
// Supports both CommonJS and ES Modules
// ES Module
import { traverse, builders as b } from 'estree-toolkit';
// CommonJS
const { traverse, builders: b } = require('estree-toolkit');
```

## Basic operations
### Traversing an AST
```js
const { traverse } = require('estree-toolkit');

traverse(ast, {
  Program(path) {
    // Do something with the path
  }
});
```
### Building Nodes
```js
const { builders: b } = require('estree-toolkit');

b.identifier('x'); // => { type: 'Identifier', name: 'x' }
```
### Checking node types
```js
const { traverse, is } = require('estree-toolkit');
const { parseModule } = require('meriyah');

const ast = parseModule(`x = 0`);

traverse(ast, {
  AssignmentExpression(path) {
    if (is.identifier(path.node.left, { name: 'x' })) {
      // `left` is an identifier with name `x`
    }
  }
});
```
### Replacing a node
```js
const { traverse, builders: b } = require('estree-toolkit');
const { parseModule } = require('meriyah');

const ast = parseModule('a = b');

traverse(ast, {
  Identifier(path) {
    if (path.node.name === 'a') {
      path.replaceWith(b.identifier('c'));
    }
  }
});

// Now the AST represents - `c = b`
```
### Collecting scope information
```js
const { traverse } = require('estree-toolkit');

traverse(ast, {
  // Enable scope
  $: { scope: true },
  Program(path) {
    // `path.scope` is now available in all paths
  }
});
```
#### Checking if a binding is available
```js
const { traverse } = require('estree-toolkit');
const { parseModule } = require('meriyah');

const ast = parseModule(`
import { a } from 'source';

const { b, c: [d, { e }] } = a;
`);

traverse(ast, {
  $: { scope: true },
  Program(path) {
    path.scope.hasBinding('a') // => true
    path.scope.hasBinding('b') // => true
    path.scope.hasBinding('c') // => false
    path.scope.hasBinding('d') // => true
    path.scope.hasBinding('e') // => true
  }
});
```
#### Getting all references of a binding
```js
const { traverse } = require('estree-toolkit');
const { parseModule } = require('meriyah');

const ast = parseModule(`
import { a } from 'source';

fn(a);
s = a;
let obj = { a };
`);

traverse(ast, {
  $: { scope: true },
  Program(path) {
    // Returns all the paths that reference the binding `a`
    path.scope.getBinding('a').references // => [NodePath, NodePath, NodePath]
  }
});
```
#### Checking if a global has been used
```js
const { traverse } = require('estree-toolkit');
const { parseModule } = require('meriyah');

const ast = parseModule(`
const fx = require('fx-mod');
`);

traverse(ast, {
  $: { scope: true },
  Program(path) {
    path.scope.hasGlobalBinding('require') // => true
  }
});
```
#### Renaming a binding
```js
const { traverse } = require('estree-toolkit');
const { parseModule } = require('meriyah');

const ast = parseModule(`
const a = 0

a.reload()
while (a.ok) a.run()
`);

traverse(ast, {
  $: { scope: true },
  Program(path) {
    // `a` -> `b`
    path.scope.renameBinding('a', 'b')
  }
});

// Output code:
// const b = 0
//
// b.reload()
// while (b.ok) b.run()
```
### Utilities
There are several static utilities that you can use.
- `evaluate`\
  Evaluates the given path.
  ```js
  const { utils: u, traverse } = require('estree-toolkit');
  // We are using `meriyah` but you can use any parser (like `acorn`)
  const { parseModule } = require('meriyah');

  traverse(parseModule(`1 + 2`), {
    BinaryExpression(path) {
      u.evaluate(path) // => { value: 3 }
    }
  });

  traverse(parseModule(`1 === 2`), {
    BinaryExpression(path) {
      u.evaluate(path) // => { value: false }
    }
  });

  traverse(parseModule(`iDoNotKnowWhatThisIs === 55`), {
    BinaryExpression(path) {
      u.evaluate(path) // => undefined
    }
  });

  traverse(parseModule(`
    ({
      text: 'This is an object',
      data: [1, 'two']
    })
  `), {
    ObjectExpression(path) {
      u.evaluate(path) // => { value: { text: 'This is an object', data: [1, 'two'] } }
    }
  });

  traverse(parseModule(`1 > 5 ? 'YES' : 'NO'`), {
    ConditionalExpression(path) {
      u.evaluate(path) // => { value: 'NO' }
    }
  });
  ```
- `evaluateTruthy`\
  Evaluates the path for truthiness and returns `true`, `false` or `undefined` depending on
  evaluation result.

There's more functionalities, please read the documentation.

## Documentation
You can find the documentation at https://estree-toolkit.netlify.app/

## Why another traverser?
I know there is [Babel](https://github.com/babel/babel). But there are
other tools which are faster than Babel. For example, [`meriyah`](https://github.com/meriyah/meriyah) is 3x faster than [`@babel/parser`](https://www.npmjs.com/package/@babel/parser), [`astring`](https://github.com/davidbonnet/astring) is up to 50x faster than [`@babel/generator`](https://www.npmjs.com/package/@babel/generator). But these tool only work with ESTree AST. I wanted to use these
faster alternatives for one of my projects but could not find any traverser with
batteries-included. So I built one myself, with awesome scope analysis, it has all the things that you would need for traversing an ESTree AST. Also, a little bit faster than Babel.

## Need help?
If you need help in any kind of ESTree AST modification, then don't hesitate to open a new discussion in [Q&A Discussions](https://github.com/sarsamurmu/estree-toolkit/discussions/categories/q-a). I will try my best to help you :)

## License
Licensed under the [MIT License](/LICENSE).

---
_Source: https://npm.io/package/estree-toolkit · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
