mrkeyoor.com_
Thu 10 Sept 18:03 UTC
Dev Toolsevaluationupdated 10 Sept 2026

ast-grep review

ast-grep is a command-line search, lint, and code-rewriting tool that matches the structure of source code instead of raw text. You write a pattern that looks like normal code, add placeholders for the parts that may vary, and use the matches for one-off changes or repeatable project rules.

trackingstars / 7d
Verdict

Our ast-grep install took 271 seconds, but its build finished in 4 seconds and pip-audit found 0 known vulnerabilities. Use it for syntax-aware searches, repository rules, and codemods that can be expressed from tree structure alone. Choose a semantic refactoring tool when types or cross-file references decide whether a change is safe, and add your own test command because our package harness found none.

We ran it

Lab card: what happened when we ran ast-grepScreenshot of ast-grep (ast-grep.github.io)
Install✓ · 271s36 packages · 85 MB
Build✓ · 4s
Testsn/ano test script
Known vulns0(pip-audit)
Repo320 files~47,902 lines of source · 3 MB · 6 CI workflows

Answers from our run

Does ast-grep build from source?

Dependencies installed in 271 seconds (36 packages), and the build succeeded in 4 seconds. We cloned commit fc2b153 into a clean Debian container with 3 CPUs and no project-specific setup.

Does ast-grep have tests you can run?

Not through a standard command: the project exposes no test script or target that our harness could run.

Does ast-grep have known vulnerabilities in its dependencies?

pip-audit found none in the dependency tree at the time of our run.

Who should not use ast-grep?

Refactors that require types, symbol resolution, imports, or cross-file reference knowledge: open issue 2413 says version 0.45.3 has no structured semantic layer for those facts.

What are the alternatives to ast-grep?

Semgrep, Comby, jscodeshift. Our ast-grep install took 271 seconds, but its build finished in 4 seconds and pip-audit found 0 known vulnerabilities.

Setup4/5Many package routes, though our pip install took 271 seconds
Docs5/5Clear patterns, rules, APIs, playground, and deployment options
Community5/515,835 stars, same-day push, and active issue discussion
Maturity4/5Active 0.45.3 release, broad packaging, and defined syntax limits

Who it’s for

Developers replacing an API pattern across a large repository where text search would catch comments or miss syntax variations.
Teams that want custom lint rules written in YAML instead of building a compiler plugin.
Library maintainers shipping codemods for breaking changes.
Tool authors who need Rust, JavaScript, or Python access to tree-sitter syntax trees.

Who it’s NOT for

Refactors that require types, symbol resolution, imports, or cross-file reference knowledge: open issue 2413 says version 0.45.3 has no structured semantic layer for those facts.
Security teams wanting a supplied policy catalog and hosted findings workflow: ast-grep provides a matching engine and expects you to author or obtain the rules.
Jobs that are genuinely textual, such as finding a phrase in documentation: the README describes AST-node matching, so ripgrep is simpler when syntax is irrelevant.
Integrations that depend on inline rules reusing project utility rules: issue 2927 reports that scan --inline-rules in 0.45.3 does not bind utilities from utilDirs.
Buyers who require a test command discovered by their standard Python package harness: our run found no tests script or target and skipped that step.

Setup reality

Our sandbox installed the Python-packaged route in 271 seconds, adding 36 packages and using 85 MB. The build succeeded in 4 seconds. No tests script or target was available to the harness, so tests were skipped; pip-audit found 0 known vulnerabilities.

The normal user install needs no account or service. The README offers npm, pip, Cargo, cargo-binstall, Homebrew, Scoop, mise, and MacPorts. Building from the checkout needs rustup, and project-wide linting or rewriting needs an sgconfig.yml plus rule files.

The codebase is Rust even though the pip distribution uses a Python build front end. npm users may need pnpm approve-builds, and the short sg command can collide with the Unix group-switching utility documented in issue 56. Custom languages need a compatible tree-sitter grammar and configuration.

Version 0.45.3 matches syntax rather than character sequences

ast-grep parses code with tree-sitter and compares syntax nodes to a pattern written in the target language. A pattern such as $A && $A() uses the uppercase placeholder as a wildcard, so formatting and ordinary identifier changes do not defeat the match. The replacement can reuse captured nodes. This sits in the useful middle between grep, which knows only text, and a compiler API, which makes you write a transformation program.

The approach is easy to try in the online playground before installing anything. On a real repository, ast-grep can search, replace interactively, or apply a rewrite across files. Its compiled Rust implementation uses multiple CPU cores, according to the README. Syntax awareness also cuts false matches in strings and comments, provided the selected tree-sitter grammar parses the code as expected. A malformed file or wrong language selection changes the tree, so previewing the diff remains part of the job.

One YAML configuration turns a pattern into a project rule

Project use starts with sgconfig.yml, rule directories, and YAML files that describe matches, constraints, severity, and fixes. Version 0.45.3 adds a minimum-severity CLI option, which helps CI jobs decide which findings should fail a run. Rules can enforce a house convention or package a migration without compiling a custom linter. Library maintainers can publish the same rule used internally so users can update call sites after an API change.

YAML becomes harder to read once a match depends on several relationships. ast-grep supplies node traversal, utility rules, and constraints, but those concepts still need to be learned. Open issue 2927 documents a current composition gap: in 0.45.3, an inline rule cannot resolve global utilities from utilDirs, even when a project configuration is passed. File-based rules work in the reporter's reproduction. Editor and MCP integrations generating temporary rules may therefore need to inline utility bodies or write rule files.

What happened when we ran it

Our sandbox used commit fc2b153 and installed the Python-packaged route in 271 seconds. It added 36 packages and consumed 85 MB. The checkout was much smaller at 3 MB, with 320 files and about 47,902 lines of source. Installation succeeded, then the build completed in 4 seconds. Six CI workflow files were present, while the scan found no Dockerfile and no top-level tests directory.

The harness found no tests script or target, so it skipped the test step. That is different from a passing suite. ast-grep is a Rust workspace with fixtures and CI configuration, while its pyproject.toml uses maturin to publish the CLI through Python packaging. Our Python-oriented discovery did not select a Cargo test command. A team evaluating the source should identify and run the upstream Rust checks separately instead of treating the 4-second build as enough validation.

Pip-audit reported 0 known vulnerabilities among the 36 installed packages. That clean result applies to the environment created by our run, not every npm, Cargo, Homebrew, or operating-system package path. The repository contains a Cargo lockfile and multiple language bindings, each with its own dependency surface. The useful conclusion is narrow: the measured pip route installed and built successfully with no advisory found by pip-audit, but it offered our harness no default test target.

The README lists eight package managers and one source build

Users can install ast-grep through npm, pip, Cargo, cargo-binstall, Homebrew, Scoop, mise, or MacPorts. The source route is cargo install against the CLI crate after installing rustup. No API token, database, daemon, or cloud account is required. That makes adoption lighter than most static-analysis platforms, especially for a developer who wants one binary in a pre-commit hook or CI image.

Packaging still has edges. The README warns that pnpm may require explicit build approval. Issue 56 tracks the short sg binary name because Unix systems already use /usr/bin/sg to run a command under another group ID; the issue says deprecation of that alias has started. Scripts should call ast-grep explicitly. Teams supporting several operating systems should also pin version 0.45.3 or another chosen release rather than assuming all package managers update together.

Version 0.45.3 does not know types or cross-file symbols

Tree structure answers whether code has a certain shape. It does not by itself prove which function an identifier resolves to, what type flows through an expression, or whether a similarly named import comes from the intended module. Open issue 2413 proposes a pluggable semantic layer precisely because ast-grep currently lacks a shared way to attach symbol, type, import, scope, and reference data to nodes. Issue 334 separately asks for control-flow and data-dependency operators.

That boundary decides which migrations are safe. Renaming a syntactically distinctive call can work well. Changing every open() only when it resolves to one library, or altering an expression only when its inferred type meets a condition, calls for a language-specific compiler or semantic codemod. jscodeshift gives JavaScript migrations procedural control, while Semgrep is a better comparison for security programs with reusable policy sets. Comby suits structural templates when a supported AST grammar is unavailable.

A September 10 push and 53 issues and PRs indicate live maintenance

GitHub showed 15,835 stars, 53 open issues and pull requests, and a last push on September 10, 2026. Release 0.45.3 was published on August 31. Its notes include tree-sitter 0.27, Markdown headings in outline output, a minimum-severity switch, and dependency updates. Current issue discussion includes inline utility resolution and target-platform support, while older design proposals remain open. The combined count is a workload signal, not a count of confirmed defects.

ast-grep earns a place in a developer toolbox because a source-shaped pattern is quicker to author than a compiler extension and safer than blind text replacement. Our 271-second installation was slow for a single CLI, yet the 4-second build and 0 pip-audit findings made the package route uneventful after dependencies arrived. Use dry runs and reviewed diffs for rewrites, keep semantic refactors in language-aware tooling, and wire an explicit upstream test command into source evaluation.

Alternatives

ProjectWhat it isPick it when
SemgrepA multi-language static-analysis tool with source-like patterns and a large rule ecosystem.pick this instead when security rules, supplied policies, and a findings workflow matter more than a small rewriting CLI.
CombyA structural search-and-replace tool that works from language-aware templates without a full AST grammar.pick this instead when broad language coverage and template rewriting matter more than exact tree-sitter nodes.
jscodeshiftA JavaScript codemod toolkit for transformations written as JavaScript programs.pick this instead when the target is JavaScript or TypeScript and the migration needs procedural AST logic.

What people are saying

  1. [github-trending] ast-grep/ast-grep

Sources

  1. ast-grep repository and README
  2. ast-grep documentation
  3. ast-grep 0.45.3 release
  4. Issue 2927: inline rules do not bind global utilities
  5. Issue 2413: proposed semantic analysis API
  6. Issue 56: sg command deprecation

More dev tools reviews

unleashed-firmware · elixir · metasploit-framework · migrate · ai-usagebar · herdr-reviewr · the whole board →