npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ast-search-js

v1.10.0

Published

AST-based code search for JavaScript, TypeScript, and Vue

Readme

ast-search-js

npm

Structural code search for JS/TS/Vue — designed for large-scale refactors and AI agent workflows. Finds code by shape, not string.

Accepts a query and searches all supported files under a directory, printing each match with its file path, line, and column. Language support is provided by plugins — the core handles JS/TS/Vue; additional languages are opt-in.

Agents: see AGENTS.md for tool descriptions, output format details, and usage patterns.

Table of Contents

Example

Say you have Vue SFCs with setup() functions that improperly access this:

export default {
  setup() {
    const value = computed(() => {
      return this.testValue  // shouldn't be here
    })
  }
}

Find all such occurrences across your whole repo:

ast-search 'ObjectMethod[key.name="setup"] ThisExpression'

Output:

src/components/Foo.vue:5:13: return this.testValue
src/components/Bar.vue:9:18: return this.otherProp

Installation

npm install -g ast-search-js

# Optional: add Python support
npm install -g ast-search-python

Agent and LLM usage

ast-search is designed to work well as a tool in AI agent workflows:

  • Token-efficient — outputs only match locations, not whole file contents
  • Machine-readable--format json returns a structured array ready for parsing
  • Structurally precise — selector-based queries eliminate false positives from string matching
  • Composable--format files produces a newline-delimited list suitable for piping to xargs or subsequent tool calls
  • Multi-query — pass multiple queries in one invocation; each file is parsed once and all queries run against it, eliminating redundant I/O

Usage

ast-search <query> [query2 ...] [--dir <path>] [--format <fmt>] [--lang <id>] [--plugin <pkg>]

Multiple queries can be passed as positional arguments. All queries run against each file's AST in a single repo walk — each file is parsed once regardless of how many queries you provide. In --format json, every match includes a query field identifying which selector produced it.

| Argument | Description | Default | | ------------------ | ------------------------------------------------------------- | ------------ | | <query> [query2 ...] | One or more query strings (see Query Syntax below) | required | | -d, --dir | Root directory to search | current dir | | -f, --format | Output format: text, json, files, or count | text | | -l, --lang | Restrict search to one language backend (e.g. js, python) | all languages | | -p, --plugin | Load a language plugin package (repeatable) | none | | -C, --context | Show N lines of context around each match (like grep -C) | 0 | | --ast | Print AST for a code snippet (positional arg) or --file; useful for writing queries | off |

Output formats

  • text (default) — one match per line as file:line:col: source; when the query uses regex matchers, captured values are appended after |
  • files — unique file paths only, one per line; useful for piping to xargs
  • json — full match array as JSON; includes a captures field when regex matchers were used
  • count — per-file match counts sorted by frequency, plus a summary line; useful for scoping a refactor before running a full search

Query syntax

JavaScript / TypeScript / Vue

Queries use esquery CSS selector syntax over Babel AST node types. A few examples:

# Find all arrow functions inside a function named "setup"
ast-search 'ObjectMethod[key.name="setup"] ArrowFunctionExpression'

# Find await expressions anywhere
ast-search 'AwaitExpression'

# Find assignments inside catch clauses
ast-search 'CatchClause AssignmentExpression'

# Find logging calls across multiple methods — regex attribute matching
# Captures the matched method name: | callee.property.name=warn
ast-search 'call[callee.property.name=/^(log|info|warn|error)$/]'

Attribute selectors support both exact strings ([prop="value"]) and regex literals ([prop=/pattern/flags]). Regex matchers automatically capture the matched value in the result's captures field.

Shorthands

Common node types can be written as short keywords:

| Shorthand | Expands to | | ---------- | --------------------------- | | this | ThisExpression | | await | AwaitExpression | | yield | YieldExpression | | new | NewExpression | | call | CallExpression | | arrow | ArrowFunctionExpression | | fn | FunctionExpression | | member | MemberExpression | | ternary | ConditionalExpression | | template | TemplateLiteral | | tagged | TaggedTemplateExpression | | assign | AssignmentExpression | | binary | BinaryExpression | | logical | LogicalExpression | | spread | SpreadElement |

The original Vue this example using shorthands:

ast-search 'ObjectMethod[key.name="setup"] this'

Optional chaining

Optional chains (?.) are normalized transparently — CallExpression and MemberExpression selectors match both regular and optional-chain variants:

# Matches both items.map(...) and items?.map(...)
ast-search 'CallExpression[callee.property.name="map"]'

The optional flag is preserved on matched nodes, so you can still narrow to strictly optional calls:

ast-search 'CallExpression[optional=true]'

Python

For Python support, see ast-search-python.

Supported file types

Core: .js .ts .jsx .tsx .mjs .cjs .vue

Via plugin: see ast-search-python for .py / .pyw support.

Plugin API

Language support is extensible. See the Plugin API section in the repository README for the LanguageBackend interface and instructions for writing a language plugin.