TEXT

AST Code Analysis Superpower

Contributed by emreizzet@gmail.com

Improved by Laravel Company · 2026-09-07

Advanced AST-Based Code Analysis with ast-grep

Executive Summary

AST (Abstract Syntax Tree) pattern matching is a powerful technique for identifying code issues through structural recognition. It reveals hidden vulnerabilities, performance bottlenecks, and structural anti-patterns that manual inspection often misses. This document outlines the best practices for configuring and using ast-grep, a command-line tool designed for systematic code pattern analysis.

When to Use AST Analysis

Follow this decision tree to determine when AST analysis is appropriate:

  1. Review Complex Code: For codebases with complex structure, multi-file dependencies, or deep abstractions.
  2. Security Critical: When the code contains security-sensitive operations like token management, authentication, or cryptographic functions.
  3. Performance-Critical: For applications with heavy user traffic, real-time requirements, or complex rendering patterns.
  4. Structural Quality: When maintaining large, legacy codebases with potential for structural decay.
  5. Cross-File Patterns: For patterns that span multiple files and directories.

Configuration Options

  • Target Language: Choose from JavaScript, TypeScript, Python, or other supported languages.
  • Analysis Focus: Select from security, performance, structure, or custom patterns.
  • Severity Level: Set to ERROR (critical), WARNING (non-critical), or INFO (information).
  • Framework: Specify if the codebase uses a specific framework like React, Angular, or Django.
  • Max Nesting Depth: Set the maximum depth for structural analysis.

Essential Commands

Installation

bash
# For npm
npm install -g @ast-grep/cli

# Or, formise
mise install -g ast-grep

Running Analysis

bash
# Security scan
ast-grep run -r sg-rules/security/

# Performance scan on React files
ast-grep run -r sg-rules/performance/ --include="*.tsx,*.jsx"

# Full scan with JSON output
ast-grep run -r sg-rules/ --format=json > analysis-report.json

# Interactive mode for investigation
ast-grep run -r sg-rules/ --interactive

Pattern Categories and Examples

1. Security Patterns

  • Hardcoded Secrets: Identifies hardcoded sensitive values and credentials.
  • Insecure Token Generation: Detects insecure token generation methods.
  • Weak Authentication: Finds weak authentication mechanisms.

2. Performance Patterns

  • ${framework:React} Hook Dependencies: Identifies hooks with excessive, inefficient, or incorrect dependencies.
  • Infinite Loops: Detects loops without exit conditions or counters.
  • Memory Leaks: Identifies patterns likely to cause memory leaks.

3. Structural Patterns

  • Deep Nesting: Detects extremely nested control structures.
  • Complex Conditionals: Identifies deeply nested if-else statements.
  • Circular Dependencies: Finds circular dependencies between files.

Pattern Writing Best Practices

  1. Specificity: Write patterns that match the specific anti-pattern, not general code.
  2. Contextual Matching: Use inside or has for context constraints to reduce false positives.
  3. Negative Constraints: Use not clauses to exclude known-good cases.
  4. Language-Specific Rules: Create separate rules for JS and TS to handle type annotations.
  5. Appropriate Severity: Use ERROR for critical issues, WARNING for non-critical, and INFO for information.

Common Mistakes and Solutions

Mistake Symptom Solution
Too generic patterns High false positive rate Add context constraints
Missing inside Matches wrong locations Scope with parent context
No not clauses Matches valid patterns Exclude known-good cases
JS patterns on TS Type annotations break match Create language-specific rules

Project Setup

Initialize ast-grep

bash
ast-grep init

Create Rule Directories

bash
mkdir -p sg-rules/{security,performance,structure}

Add to CI Pipeline

yaml
# .github/workflows/lint.yml
- run: ast-grep run -r sg-rules/ --format=json

Custom Pattern Templates

React-Specific Patterns

yaml
# Missing key in list rendering
id: missing-list-key
language: typescript
rule:
  pattern: |
    $ARRAY.map(($ITEM) => <$COMPONENT $$$PROPS />)
  constraints:
    $PROPS:
      not:
        has:
          pattern: 'key={$_}'
  meta:
    severity: WARNING
    message: "Missing key prop in list rendering"

Cross-File Patterns

yaml
# Circular dependencies
id: circular-dependencies
language: typescript
rule:
  pattern: |
    import { $FUNC } from './$FILE';
    $BODY
  meta:
    severity: ERROR
    message: "Potential circular dependency detected"

Integration with CI/CD

GitHub Actions Example

yaml
name: AST Analysis
on: [push, pull_request]
jobs:
  analyze:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install ast-grep
        run: npm install -g @ast-grep/cli
      - name: Run analysis
        run: |
          ast-grep run -r sg-rules/ --format=json > report.json
          if grep -q '"severity": "ERROR"' report.json; then
            echo "Critical issues found!"
            exit 1
          fi

Verification and Validation

  1. Test pattern accuracy: Run on known-vulnerable and known-good code samples.
  2. Check false positive rate: Review first 10 matches manually.
  3. Validate severity: Confirm error-level findings are actionable.
  4. Cross-file coverage: Verify pattern runs across intended scope.

Example Output

php
$ ast-grep run -r sg-rules/
src/components/UserProfile.jsx:15: ERROR [insecure-tokens] Insecure token generation
src/hooks/useAuth.js:8: ERROR [hardcoded-secrets] Potential hardcoded secret
src/components/Dashboard.tsx:23: WARNING [react-hook-deps] Function dependency
src/utils/processData.js:45: WARNING [deep-nesting] Deep nesting detected

Found 4 issues (2 errors, 2 warnings)

This improved prompt provides a more detailed, structured, and clear overview of the ast-grep code analysis process. It includes a comprehensive decision tree, detailed pattern examples, and best practices for writing effective rules. The prompt also addresses common mistakes and provides examples of how to integrate ast-grep into CI/CD pipelines.

Original prompt (before our improvements)

--- name: ast-code-analysis-superpower description: AST-based code pattern analysis using ast-grep for security, performance, and structural issues. Use when (1) reviewing code for security vulnerabilities, (2) analyzing React hook dependencies or performance patterns, (3) detecting structural anti-patterns across large codebases, (4) needing systematic pattern matching beyond manual inspection. --- # AST-Grep Code Analysis AST pattern matching identifies code issues through structural recognition rather than line-by-line reading. Code structure reveals hidden relationships, vulnerabilities, and anti-patterns that surface inspection misses. ## Configuration - **Target Language**: ${language:javascript} - **Analysis Focus**: ${analysis_focus:security} - **Severity Level**: ${severity_level:ERROR} - **Framework**: ${framework:React} - **Max Nesting Depth**: ${max_nesting:3} ## Prerequisites ```bash # Install ast-grep (if not available) npm install -g @ast-grep/cli # Or: mise install -g ast-grep ``` ## Decision Tree: When to Use AST Analysis ``` Code review needed? | +-- Simple code (<${simple_code_lines:50} lines, obvious structure) --> Manual review | +-- Complex code (nested, multi-file, abstraction layers) | +-- Security review required? --> Use security patterns +-- Performance analysis? --> Use performance patterns +-- Structural quality? --> Use structure patterns +-- Cross-file patterns? --> Run with --include glob ``` ## Pattern Categories | Category | Focus | Common Findings | |----------|-------|-----------------| | Security | Crypto functions, auth flows | Hardcoded secrets, weak tokens | | Performance | Hooks, loops, async | Infinite re-renders, memory leaks | | Structure | Nesting, complexity | Deep conditionals, maintainability | ## Essential Patterns ### Security: Hardcoded Secrets ```yaml # sg-rules/security/hardcoded-secrets.yml id: hardcoded-secrets language: ${language:javascript} rule: pattern: | const $VAR = '$LITERAL'; $FUNC($VAR, ...) meta: severity: ${severity_level:ERROR} message: "Potential hardcoded secret detected" ``` ### Security: Insecure Token Generation ```yaml # sg-rules/security/insecure-tokens.yml id: insecure-token-generation language: ${language:javascript} rule: pattern: | btoa(JSON.stringify($OBJ) + '.' + $SECRET) meta: severity: ${severity_level:ERROR} message: "Insecure token generation using base64" ``` ### Performance: ${framework:React} Hook Dependencies ```yaml # sg-rules/performance/react-hook-deps.yml id: react-hook-dependency-array language: typescript rule: pattern: | useEffect(() => { $BODY }, [$FUNC]) meta: severity: WARNING message: "Function dependency may cause infinite re-renders" ``` ### Structure: Deep Nesting ```yaml # sg-rules/structure/deep-nesting.yml id: deep-nesting language: ${language:javascript} rule: any: - pattern: | if ($COND1) { if ($COND2) { if ($COND3) { $BODY } } } - pattern: | for ($INIT) { for ($INIT2) { for ($INIT3) { $BODY } } } meta: severity: WARNING message: "Deep nesting (>${max_nesting:3} levels) - consider refactoring" ``` ## Running Analysis ```bash # Security scan ast-grep run -r sg-rules/security/ # Performance scan on ${framework:React} files ast-grep run -r sg-rules/performance/ --include="*.tsx,*.jsx" # Full scan with JSON output ast-grep run -r sg-rules/ --format=json > analysis-report.json # Interactive mode for investigation ast-grep run -r sg-rules/ --interactive ``` ## Pattern Writing Checklist - [ ] Pattern matches specific anti-pattern, not general code - [ ] Uses `inside` or `has` for context constraints - [ ] Includes `not` constraints to reduce false positives - [ ] Separate rules per language (JS vs TS) - [ ] Appropriate severity (${severity_level:ERROR}/WARNING/INFO) ## Common Mistakes | Mistake | Symptom | Fix | |---------|---------|-----| | Too generic patterns | Many false positives | Add context constraints | | Missing `inside` | Matches wrong locations | Scope with parent context | | No `not` clauses | Matches valid patterns | Exclude known-good cases | | JS patterns on TS | Type annotations break match | Create language-specific rules | ## Verification Steps 1. **Test pattern accuracy**: Run on known-vulnerable code samples 2. **Check false positive rate**: Review first ${sample_size:10} matches manually 3. **Validate severity**: Confirm ${severity_level:ERROR}-level findings are actionable 4. **Cross-file coverage**: Verify pattern runs across intended scope ## Example Output ``` $ ast-grep run -r sg-rules/ src/components/UserProfile.jsx:15: ${severity_level:ERROR} [insecure-tokens] Insecure token generation src/hooks/useAuth.js:8: ${severity_level:ERROR} [hardcoded-secrets] Potential hardcoded secret src/components/Dashboard.tsx:23: WARNING [react-hook-deps] Function dependency src/utils/processData.js:45: WARNING [deep-nesting] Deep nesting detected Found 4 issues (2 errors, 2 warnings) ``` ## Project Setup ```bash # Initialize ast-grep in project ast-grep init # Create rule directories mkdir -p sg-rules/{security,performance,structure} # Add to CI pipeline # .github/workflows/lint.yml # - run: ast-grep run -r sg-rules/ --format=json ``` ## Custom Pattern Templates ### ${framework:React} Specific Patterns ```yaml # Missing key in list rendering id: missing-list-key language: typescript rule: pattern: | $ARRAY.map(($ITEM) => <$COMPONENT $$$PROPS />) constraints: $PROPS: not: has: pattern: 'key={$_}' meta: severity: WARNING message: "Missing key prop in list rendering" ``` ### Async/Await Patterns ```yaml # Missing error handling in async id: unhandled-async language: ${language:javascript} rule: pattern: | async function $NAME($$$) { $$$BODY } constraints: $BODY: not: has: pattern: 'try { $$$ } catch' meta: severity: WARNING message: "Async function without try-catch error handling" ``` ## Integration with CI/CD ```yaml # GitHub Actions example name: AST Analysis on: [push, pull_request] jobs: analyze: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Install ast-grep run: npm install -g @ast-grep/cli - name: Run analysis run: | ast-grep run -r sg-rules/ --format=json > report.json if grep -q '"severity": "${severity_level:ERROR}"' report.json; then echo "Critical issues found!" exit 1 fi ```