# @rushstack/tree-pattern

> A fast, lightweight pattern matcher for tree structures such as an Abstract Syntax Tree (AST)

Latest version **0.4.1** (published 2026-02-20) · MIT license · 0 weekly downloads

## Install

```sh
npm install @rushstack/tree-pattern
pnpm add @rushstack/tree-pattern
yarn add @rushstack/tree-pattern
bun add @rushstack/tree-pattern
```

## Health

**Score 55/100 (C)** — status: stable.

Positive: has types; esm support; no vulnerabilities.

Warnings: low downloads; pre 1.0.

## Facts

| | |
|---|---|
| Version | 0.4.1 |
| Published | 2026-02-20 |
| First published | 2020-09-19 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 0 |
| Unpacked size | 63.9 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Maintainers | rushstack-admin, odspnpm, octogonz |

## Links

- npm: https://www.npmjs.com/package/@rushstack/tree-pattern
- Repository: https://github.com/microsoft/rushstack
- Homepage: https://github.com/microsoft/rushstack#readme
- Issues: https://github.com/microsoft/rushstack/issues
- npm.io page: https://npm.io/package/@rushstack/tree-pattern

## Recent versions

- 0.4.1 (latest) — 2026-02-20
- 0.4.0 — 2026-02-19
- 0.3.4 — 2024-07-27
- 0.3.3 — 2024-02-17
- 0.3.2 — 2024-01-16
- 0.3.1 — 2023-09-26
- 0.3.0 — 2023-09-15
- 0.2.4 — 2022-06-17
- 0.2.3 — 2022-04-09
- 0.2.2 — 2021-10-27
- 0.2.1 — 2020-09-30
- 0.2.0 — 2020-09-30
- 0.1.0 — 2020-09-19
- 0.0.0 — 2020-09-19

## README

# @rushstack/tree-pattern

This is a simple, fast pattern matcher for JavaScript tree structures.  It was designed for ESLint rules and
transforms that match parse trees such as produced by [Esprima](https://esprima.org/). However, it can be used
with any JSON-like data structure.

## Usage

Suppose we are fixing up obsolete `Promise` calls, and we need to match an input like this:

```ts
Promise.fulfilled(123);
```

The parsed subtree looks like this:
```js
{
  "type": "Program",
  "body": [
    {
      "type": "ExpressionStatement",
      "expression": {  // <---- expressionNode
        "type": "CallExpression",
        "callee": {
          "type": "MemberExpression",
          "object": {
            "type": "Identifier",
            "name": "Promise"
          },
          "property": {
            "type": "Identifier",
            "name": "fulfilled"
          },
          "computed": false,
          "optional": false
        },
        "arguments": [
          {
            "type": "Literal",
            "value": 123,
            "raw": "123"
          }
        ],
        "optional": false
      }
    }
  ],
  "sourceType": "module"
}
```

Throwing away the details that we don't care about, we can specify a pattern expression with the parts
that need to be present:
```js
const pattern1: TreePattern = new TreePattern({
  type: 'CallExpression',
  callee: {
    type: 'MemberExpression',
    object: {
      type: 'Identifier',
      name: 'Promise'
    },
    property: {
      type: 'Identifier',
      name: 'fulfilled'
    },
    computed: false
  }
});
```

Then when our visitor encounters an `ExpressionStatement`, we can match the `expressionNode` like this:
```js
if (pattern1.match(expressionNode)) {
  console.log('Success!');
}
```

## Capturing matched subtrees

Suppose we want to generalize this to match any API such as `Promise.thing(123);` or `Promise.otherThing(123);`.
We can use a "tag" to extract the matching identifier:

```js
const pattern2: TreePattern = new TreePattern({
  type: 'CallExpression',
  callee: {
    type: 'MemberExpression',
    object: {
      type: 'Identifier',
      name: 'Promise'
    },
    property: TreePattern.tag('promiseMethod', {
      type: 'Identifier'
    }),
    computed: false
  }
});
```

On a successful match, the tagged `promiseMethod` subtree can be retrieved like this:
```ts
interface IMyCaptures {
  // Captures the "promiseMethod" tag specified using TreePattern.tag()
  promiseMethod?: { name?: string }; // <--- substitute your real AST interface here
}

const captures: IMyCaptures = {};

if (pattern2.match(node, captures)) {
  // Prints: "Matched fulfilled"
  console.log('Matched ' + captures?.promiseMethod?.name);
}
```

## Alternative subtrees

The `oneOf` API enables you to write patterns that match alternative subtrees.

```ts
const pattern3: TreePattern = new TreePattern({
  animal: TreePattern.oneOf([
    { kind: 'dog', bark: 'loud' },
    { kind: 'cat', meow: 'quiet' }
  ])
});

if (pattern3.match({ animal: { kind: 'dog', bark: 'loud' } })) {
  console.log('I can match dog.');
}

if (pattern3.match({ animal: { kind: 'cat', meow: 'quiet' } })) {
  console.log('I can match cat, too.');
}
```

For example, maybe we want to match `Promise['fulfilled'](123);` as well as `Promise.fulfilled(123);`.
If the structure of the expressions is similar enough, `TreePattern.oneOf` avoids having to create two
separate patterns.

## Links

- [CHANGELOG.md](
  https://github.com/microsoft/rushstack/blob/main/libraries/tree-pattern/CHANGELOG.md) - Find
  out what's new in the latest version
- [API Reference](https://api.rushstack.io/pages/tree-pattern/)

`@rushstack/tree-pattern` is part of the [Rush Stack](https://rushstack.io/) family of projects.

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