> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coderabbit.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# AST-based path instructions

> Write structural code pattern rules using ast-grep to give CodeRabbit precise, syntax-aware review instructions.

export const ProPlanBadge = ({tip = "This feature is available as part of the Pro, Pro+ and Enterprise plans. Please refer to our pricing page for more information about our plans and features.", title = "Pro Plan", cta = "Read more", href = "https://coderabbit.ai/pricing", disabled = false}) => {
  return <Tooltip tip={tip} cta={cta} href={href}>
        <Badge icon="shield-check" disabled={disabled || undefined}>
            {title}
        </Badge>
    </Tooltip>;
};

export const AllPlatformsBadge = ({tip = "This feature is available on all supported platforms: GitHub, GitLab, Azure DevOps, and Bitbucket.", title = "All Platforms", cta, href, disabled = false}) => {
  return <Tooltip tip={tip} cta={cta} href={href}>
        <Badge icon="globe" disabled={disabled || undefined}>
            {title}
        </Badge>
    </Tooltip>;
};

<AllPlatformsBadge /> | <ProPlanBadge />

CodeRabbit supports review instructions based on Abstract Syntax Tree (AST) patterns, powered by [`ast-grep`](https://ast-grep.github.io) — a Rust-based tool that uses the tree-sitter parser to generate AST rules for popular languages, written by [Herrington Darkholme](https://twitter.com/hd_nvim). This feature has a learning curve and is recommended for users already comfortable with YAML configuration.

<Info>
  AST-based context is only available during the automated code review process, it is not available in the chat.
</Info>

**Further reading:**

* [Abstract Syntax Tree](https://en.wikipedia.org/wiki/Abstract_syntax_tree) — Wikipedia
* [`ast-grep` rule configuration guide](https://ast-grep.github.io/guide/rule-config.html)

## Setup

Use the [ast-grep Playground](https://ast-grep.github.io/playground.html) to design and test rules on source code snippets before adding them to your project.

<Steps>
  <Step title="Create rules directory">
    Create a directory to keep all the `ast-grep` rules in your project
    directory
  </Step>

  <Step title="Add rule files">
    Add individual `.yaml` files for each `ast-grep` rule within the newly
    created directory
  </Step>

  <Step title="Configure rules">
    Ensure that each `.yaml` file contains the necessary `ast-grep` rule
    configurations
  </Step>

  <Step title="Add message property">
    Ensure that all rules contain a `message` property that will be used during
    the review process
  </Step>

  <Step title="Update configuration">
    Add the rules' directory to the `.coderabbit.yaml` file under
    `tools.ast-grep` configuration
  </Step>

  <Step title="Add packages (optional)">
    Optionally, add a `packages` property to specify packages that should be
    installed before running the `ast-grep` tool
  </Step>
</Steps>

```yaml YAML lines wrap icon="code" theme={null}
reviews:
  tools:
    ast-grep:
      essential_rules: true # option to enable essential security rules
      rule_dirs:
        - "custom-name"
      packages:
        - "myorg/myawesomepackage" # custom package name following the format organization/repository
```

## The rule object

The rule object is the core concept of the `ast-grep` rule system — every other feature is built on top of it.

Below is the full list of fields in a rule object. Every field is optional and can be omitted, but at least one field must be present. A node matches a rule if and only if it satisfies all fields in the rule object.

```yaml YAML lines wrap icon="code" theme={null}
rule:
  # atomic rule
  pattern: "search.pattern"
  kind: "tree_sitter_node_kind"
  regex: "rust|regex"
  # relational rule
  inside: { pattern: "sub.rule" }
  has: { kind: "sub_rule" }
  follows: { regex: "can|use|any" }
  precedes: { kind: "multi_keys", pattern: "in.sub" }
  # composite rule
  all: [{ pattern: "match.all" }, { kind: "match_all" }]
  any: [{ pattern: "match.any" }, { kind: "match_any" }]
  not: { pattern: "not.this" }
  matches: "utility-rule"
```

## Rule categories

<CardGroup cols={3}>
  <Card title="Atomic Rule" icon="atom">
    The most basic rule that checks if AST nodes match
  </Card>

  <Card title="Relational Rule" icon="link">
    Rules that check if a node is surrounded by another node
  </Card>

  <Card title="Composite Rule" icon="puzzle">
    Rules that combine sub-rules together using logical operators
  </Card>
</CardGroup>

These three categories can be composed together to create more complex rules.

<Tip>
  The rule object is inspired by CSS selectors but with more composability and
  expressiveness. Think about how CSS selectors work to better understand rule
  composition.
</Tip>

> Read the `ast-grep` [documentation](https://ast-grep.github.io/guide/rule-config.html) for detailed guides.

### Atomic rule

An atomic rule defines the most basic matching rule: whether a syntax node matches or not. There are three kinds: `pattern`, `kind`, and `regex`.

> Official documentation: [Atomic Rule](https://ast-grep.github.io/guide/rule-config/atomic-rule.html)

### Relational rule

A relational rule defines the relationship between two syntax nodes. There are four kinds: `inside`, `has`, `follows`, and `precedes`.

All four relational rules accept a sub-rule object as their value. The sub-rule matches the surrounding node; the relational rule itself matches the target node.

> Official documentation: [Relational Rule](https://ast-grep.github.io/guide/rule-config/relational-rule.html)

```yaml YAML lines wrap icon="code" theme={null}
rule:
  pattern: await $PROMISE
  inside:
    kind: for_in_statement
    stopBy: end
```

### Composite rule

A composite rule defines the logical relationship between multiple sub-rules. There are three kinds: `all`, `any`, and `not`.

**`all`** — matches if all sub-rules match:

```yaml YAML lines wrap icon="code" theme={null}
rule:
  all:
    - pattern: console.log('Hello World');
    - kind: expression_statement
```

**`any`** — matches if any sub-rule matches:

```yaml YAML lines wrap icon="code" theme={null}
rule:
  any:
    - pattern: var a = $A
    - pattern: const a = $A
    - pattern: let a = $A
```

**`not`** — applies negation; matches if the sub-rule does not match:

```yaml YAML lines wrap icon="code" theme={null}
rule:
  pattern: console.log($GREETING)
  not:
    pattern: console.log('Hello World')
```

> Official documentation: [Composite Rule](https://ast-grep.github.io/guide/rule-config/composite-rule.html)

## Reusing rules as utilities

`ast-grep` uses YAML for rule representation, which means rule objects cannot be directly reused across rule files. Utility rules solve this.

### Local utility rule

Local utility rules are defined in the `utils` field of the config file. `utils` is a string-keyed dictionary.

```yaml YAML lines wrap icon="code" theme={null}
utils:
  is-literal:
    any:
      - kind: string
      - kind: number
      - kind: boolean
rule:
  matches: is-literal
```

### Global utility rule

Global utility rules are defined in a separate file and are available across all rule configurations in the project.

To create global utility rules, create a `rules` directory and a `utils` directory at the root of your project:

```yaml YAML lines wrap icon="code" theme={null}
my-awesome-project   # project root
  |- rules           # rule directory
  | |- my-rule.yml
  |- utils           # utils directory
  | |- is-literal.yml
```

Add both directories to `.coderabbit.yaml` under `tools.ast-grep`:

```yaml YAML lines wrap icon="code" theme={null}
reviews:
  tools:
    ast-grep:
      essential_rules: true
      rule_dirs:
        - "rules"
      util_dirs:
        - "utils"
      packages:
        - "my-awesome-org/my-awesome-package" # public repository containing ast-grep rules
```

Example utility rule file:

```yaml YAML lines wrap icon="code" theme={null}
# is-literal.yml
id: is-literal
language: TypeScript
rule:
  any:
    - kind: "false"
    - kind: undefined
    - kind: "null"
    - kind: "true"
    - kind: regex
    - kind: number
    - kind: string
```

> Official documentation: [Utility Rule](https://ast-grep.github.io/guide/rule-config/utility-rule.html)

## Packages

A package is a collection of `ast-grep` rules that can be shared across multiple projects.

<CardGroup cols={2}>
  <Card title="Built-in packages" icon="package">
    CodeRabbit provides packages you can use out of the box
  </Card>

  <Card title="Custom packages" icon="box">
    Create your own packages and share them with your organization or community
  </Card>
</CardGroup>

### CodeRabbit packages

<Card title="ast-grep-essentials" icon="shield" href="https://github.com/coderabbitai/ast-grep-essentials">
  **Essential security rules package**

  Because we value security, this package gets its own property in `.coderabbit.yaml` for easier installation without overwriting existing configurations.
</Card>

```yaml YAML lines wrap icon="code" theme={null}
reviews:
  tools:
    ast-grep:
      essential_rules: true
      packages:
        - "my-awesome-org/my-awesome-package"
```

### Custom packages

To use a public repository containing `ast-grep` rules as a package, add it to the `packages` field in `.coderabbit.yaml`.

<AccordionGroup>
  <Accordion title="Repository requirements">
    * Must be a public repository
    * Name must follow the format `organization/repository`
  </Accordion>

  <Accordion title="Content requirements">
    * Contains rules that follow the `ast-grep` rule format
    * Follows the required folder structure shown below
  </Accordion>

  <Accordion title="Folder structure">
    ```text theme={null}
    my-awesome-project   # project root
      |- rules           # rule directory
      | |- my-rule.yml
      |- utils           # utils directory
      | |- is-literal.yml
    ```

    <Info>
      `rules` and `utils` are reserved directory names and must be named exactly as shown. Inside each directory, the structure is flexible.
    </Info>
  </Accordion>
</AccordionGroup>

```yaml YAML lines wrap icon="code" theme={null}
reviews:
  tools:
    ast-grep:
      packages:
        - "my-awesome-org/my-awesome-package"
```

## Supported languages

<CardGroup cols={3}>
  <Card title="Web Technologies" icon="globe">
    * JavaScript
    * TypeScript
  </Card>

  <Card title="Systems Languages" icon="microchip">
    * C
    * Rust
    * Golang
  </Card>

  <Card title="Enterprise Languages" icon="building">
    * Java
    * C#
    * Kotlin
    * Python
  </Card>
</CardGroup>

## Examples

### JavaScript — disallow imports without file extension

```yaml YAML lines wrap icon="code" theme={null}
id: find-import-file
language: js
message: "Importing files without an extension is not allowed"
rule:
  regex: "/[^.]+[^/]$"
  kind: string_fragment
  any:
    - inside:
        stopBy: end
        kind: import_statement
    - inside:
        stopBy: end
        kind: call_expression
        has:
          field: function
          regex: "^import$"
```

### TypeScript — no `console.log` except `console.error` in catch blocks

```yaml YAML lines wrap icon="code" theme={null}
id: no-console-except-error
language: typescript
message: "No console.log allowed except console.error on the catch block"
rule:
  any:
    - pattern: console.error($$$)
      not:
        inside:
          kind: catch_clause
          stopBy: end
    - pattern: console.$METHOD($$$)
constraints:
  METHOD:
    regex: "log|debug|warn"
```

### C — prefer plain function calls over struct method-style calls

In C, simulating OOP via struct function pointers introduces memory and indirection overhead. This rule flags the pattern and suggests a plain function call with the struct pointer as the first argument.

```yaml YAML lines wrap icon="code" theme={null}
id: method_receiver
language: c
rule:
  pattern: $R.$METHOD($$$ARGS)
transform:
  MAYBE_COMMA:
    replace:
      source: $$$ARGS
      replace: "^.+"
      by: ", "
fix: $METHOD(&$R$MAYBE_COMMA$$$ARGS)
```

## What's next

<CardGroup cols={1}>
  <Card title="Path-based review instructions" icon="folder" href="/configuration/path-instructions" horizontal>
    Apply free-text review guidance to specific file paths and directories using glob patterns.
  </Card>

  <Card title="Tools overview" icon="wrench" href="/tools/index" horizontal>
    See all static analysis and linting tools that CodeRabbit integrates with, including ast-grep.
  </Card>
</CardGroup>
