# How Ignore Pattern Matching Works in Claude Context for Codebases

> Discover how Claude Context with zilliztech/claude-context efficiently ignores files using a layered pattern engine. Learn about glob patterns, custom configs, and env vars for optimized code analysis.

- Repository: [Zilliz/claude-context](https://github.com/zilliztech/claude-context)
- Tags: how-to-guide
- Published: 2026-04-22

---

**Claude Context uses a layered ignore-pattern engine that evaluates glob patterns against file paths before any filesystem access, combining default patterns, custom configurations, environment variables, and standard ignore files into a single deduplicated list.**

The ignore pattern matching algorithm in Claude Context determines which files enter the indexing pipeline by filtering a candidate set against multiple pattern sources. This process occurs entirely in memory before `fs.stat` or `fs.readFile` operations, ensuring ignored files never trigger disk I/O. The implementation spans [`packages/core/src/context.ts`](https://github.com/zilliztech/claude-context/blob/main/packages/core/src/context.ts) for pattern collection and [`packages/core/src/sync/synchronizer.ts`](https://github.com/zilliztech/claude-context/blob/main/packages/core/src/sync/synchronizer.ts) for the matching engine itself.

## Sources of Ignore Patterns in Claude Context

Claude Context aggregates ignore patterns from seven distinct sources, merging them into a unified array that the `FileSynchronizer` receives during initialization.

### Default and Hard-Coded Patterns

The base pattern set originates from `DEFAULT_IGNORE_PATTERNS` in [`packages/core/src/context.ts`](https://github.com/zilliztech/claude-context/blob/main/packages/core/src/context.ts). These cover common exclusions like version control, dependency directories, and build artifacts that should never be indexed regardless of project configuration.

### Runtime Custom Patterns via MCP and API

When instantiating a `Context` directly or through the Model Context Protocol (MCP), you can supply additional patterns through the `customIgnorePatterns` field of the configuration object. The `addCustomIgnorePatterns()` method in [`context.ts`](https://github.com/zilliztech/claude-context/blob/main/context.ts) appends these to the internal `ignorePatterns` array.

### Environment Variable CUSTOM_IGNORE_PATTERNS

The `Context.getCustomIgnorePatternsFromEnv()` method reads comma-separated patterns from the `CUSTOM_IGNORE_PATTERNS` environment variable, enabling CI/CD pipelines and shell scripts to inject exclusions without modifying code:

```bash
export CUSTOM_IGNORE_PATTERNS="node_modules/**,dist/**,.env*"

```

### Project-Level .gitignore

The `Context.loadIgnoreFile()` generic loader parses `.gitignore` from the project root, treating its patterns as additional exclusion rules. This ensures Claude Context respects the same boundaries as Git.

### Custom .*ignore Files

The `Context.findIgnoreFiles()` discovery mechanism locates editor-specific ignore files like `.cursorignore` or `.codeiumignore`, merging their contents into the pattern set. This accommodates toolchain-specific exclusions without polluting `.gitignore`.

### Global ~/.context/.contextignore

Finally, `Context.loadGlobalIgnoreFile()` loads patterns from the user's home directory, applying user-wide exclusions across all projects indexed by Claude Context.

All sources converge in `Context.loadIgnorePatterns()`, which deduplicates patterns before handing them to the `FileSynchronizer` constructor.

## The Matching Algorithm in FileSynchronizer

The core matching logic resides in [`packages/core/src/sync/synchronizer.ts`](https://github.com/zilliztech/claude-context/blob/main/packages/core/src/sync/synchronizer.ts), specifically within `FileSynchronizer.shouldIgnore()`. This method evaluates every candidate path before any filesystem operation occurs.

### Pre-Stat Evaluation Design

`FileSynchronizer` walks the directory tree recursively. For each entry, it calls `shouldIgnore(relativePath, isDirectory)` immediately. This design guarantees that ignored files never trigger `fs.stat`, `fs.readFile`, or similar operations, minimizing I/O overhead for large projects with extensive dependency trees.

### Step-by-Step Matching Flow

The `shouldIgnore` implementation follows a strict evaluation order:

```typescript
shouldIgnore(relativePath: string, isDirectory: boolean): boolean {
    // 1. Hidden files and directories (prefix '.') are always excluded
    if (pathParts.some(p => p.startsWith('.'))) {
        return true;
    }

    // 2. Empty pattern set means no exclusions
    if (this.ignorePatterns.length === 0) {
        return false;
    }

    // 3. Normalize path to forward slashes, trim slashes
    const normalized = relativePath
        .replace(/\\/g, '/')
        .replace(/^\/+|\/+$/g, '');
    if (!normalized) {
        return false;  // never ignore the root itself
    }

    // 4. Direct pattern matching against full normalized path
    for (const pattern of this.ignorePatterns) {
        if (this.matchPattern(normalized, pattern, isDirectory)) {
            return true;
        }
    }

    // 5. Parent-directory cascade check
    const parts = normalized.split('/');
    for (let i = 0; i < parts.length; i++) {
        const partial = parts.slice(0, i + 1).join('/');
        for (const pattern of this.ignorePatterns) {
            // Directory-only pattern (trailing slash)
            if (pattern.endsWith('/') && 
                this.simpleGlobMatch(partial, pattern.slice(0, -1))) {
                return true;
            }
            // Full-path glob pattern
            if (pattern.includes('/') && 
                this.simpleGlobMatch(partial, pattern)) {
                return true;
            }
            // Filename glob applied to each component
            if (!pattern.includes('/') && 
                this.simpleGlobMatch(parts[i], pattern)) {
                return true;
            }
        }
    }
    return false;
}

```

### Three-Mode Pattern Classification

The `matchPattern` helper in `FileSynchronizer` categorizes each pattern into one of three matching modes:

| Pattern Type | Identification | Matching Behavior |
|-------------|----------------|-------------------|
| **Directory-only** | Ends with `/` | Matches only directories; applied to full path or any parent segment |
| **Full-path glob** | Contains `/` but doesn't end with `/` | Matches entire normalized path against the pattern |
| **Filename glob** | No `/` characters | Matches only the final path component (basename) |

This classification enables precise control: `node_modules/` ignores the entire directory tree, `src/**/*.test.ts` ignores test files in any `src` subdirectory, and `*.log` ignores log files regardless of location.

### The simpleGlobMatch Implementation

The glob-to-regex conversion resides in `simpleGlobMatch`, which supports only the `*` wildcard:

```typescript
simpleGlobMatch(text: string, pattern: string): boolean {
    const regex = new RegExp('^' +
        pattern
            .replace(/[.+^${}()|[\]\\]/g, '\\$&')  // escape regex metacharacters
            .replace(/\*/g, '.*')                    // * matches any sequence
        + '$'
    );
    return regex.test(text);
}

```

This implementation intentionally excludes `?` and `**` to maintain predictable performance. Patterns like `node_modules/**` become `node_modules/.*` in regex form, which correctly matches any path starting with `node_modules/`.

## Practical Configuration Examples

### Instantiating Context with Custom Ignore Patterns

```typescript
import { Context } from '@claude/context';
import { MilvusVectorDatabase } from '@claude/vectordb-milvus';

const ctx = new Context({
    vectorDatabase: new MilvusVectorDatabase({ /* configuration */ }),
    customIgnorePatterns: [
        'temp/**',      // temporary directories
        '*.bak',        // backup files
        'private/**'    // sensitive content
    ]
});

await ctx.indexCodebase('/path/to/project');

```

The `customIgnorePatterns` array passes through `addCustomIgnorePatterns()` in [`packages/core/src/context.ts`](https://github.com/zilliztech/claude-context/blob/main/packages/core/src/context.ts) before reaching the `FileSynchronizer`.

### Environment-Based Configuration

```bash

# Multiple patterns separated by commas

export CUSTOM_IGNORE_PATTERNS="node_modules/**,dist/**,.env*,coverage/**"

# Optional: extend supported extensions

export CUSTOM_EXTENSIONS=".vue,.svelte,.astro"

node run-indexer.js

```

The `Context.getCustomIgnorePatternsFromEnv()` and `Context.getCustomExtensionsFromEnv()` methods in [`context.ts`](https://github.com/zilliztech/claude-context/blob/main/context.ts) parse these variables automatically.

### Debug Output for Pattern Matching

To observe which paths get excluded, enable debug logging during synchronization:

```typescript
// Inside FileSynchronizer.generateFileHashes()
if (this.shouldIgnore(relativePath, entry.isDirectory())) {
    console.log(`[Synchronizer] Ignored ${relativePath}`);
    continue;
}

```

Typical output shows the algorithm in action:

```

[Synchronizer] Ignored node_modules/@types/react/index.d.ts
[Synchronizer] Ignored .git/config
[Synchronizer] Ignored logs/app.log

```

## Performance Characteristics

The `FileSynchronizer` implementation prioritizes early termination and minimal overhead:

| Optimization | Implementation |
|-------------|----------------|
| **Hidden file fast-path** | Checked before pattern iteration—no regex compilation for `.git`, `.env`, etc. |
| **Empty pattern short-circuit** | Returns `false` immediately when no patterns configured |
| **Single-pass normalization** | Path cleaning happens once, reused for all pattern checks |
| **Early return on match** | `return true` immediately when any pattern matches |
| **Compiled regex caching** | `simpleGlobMatch` could cache regex objects (implementation-dependent) |

The parent-directory cascade check (step 5 in `shouldIgnore`) adds overhead proportional to path depth, but eliminates false positives where a directory pattern should exclude nested contents.

## Summary

- Claude Context aggregates ignore patterns from **seven sources**: defaults, MCP parameters, environment variables, `.gitignore`, custom `.*ignore` files, and a global `~/.context/.contextignore`
- The `FileSynchronizer` in [`packages/core/src/sync/synchronizer.ts`](https://github.com/zilliztech/claude-context/blob/main/packages/core/src/sync/synchronizer.ts) evaluates paths **before any filesystem access** via `shouldIgnore()`
- Pattern matching uses **three modes**: directory-only (trailing `/`), full-path glob (contains `/`), and filename glob (no `/`)
- The `simpleGlobMatch` helper converts glob patterns to regexes, supporting only `*` wildcards for predictable performance
- Hidden files and directories are **always excluded** regardless of pattern configuration

## Frequently Asked Questions

### What pattern syntax does Claude Context support?

Claude Context supports a **subset of glob syntax** limited to the `*` wildcard. Patterns may end with `/` to indicate directory-only matching, contain `/` for full-path matching, or omit slashes for filename matching. The `simpleGlobMatch` function in [`synchronizer.ts`](https://github.com/zilliztech/claude-context/blob/main/synchronizer.ts) explicitly does not support `?` or `**` quantifiers to maintain deterministic performance characteristics.

### How do I add custom ignore patterns without modifying code?

Set the `CUSTOM_IGNORE_PATTERNS` environment variable with comma-separated patterns before running the indexer. The `Context.getCustomIgnorePatternsFromEnv()` method in [`context.ts`](https://github.com/zilliztech/claude-context/blob/main/context.ts) automatically parses and merges these patterns. Alternatively, create a `.contextignore` file in your project root or at `~/.context/.contextignore` for user-wide exclusions.

### Why are hidden files always ignored regardless of my patterns?

The `FileSynchronizer.shouldIgnore()` method implements a **fast-path check** that immediately returns `true` for any path component starting with `.` (dot). This hard-coded rule in [`synchronizer.ts`](https://github.com/zilliztech/claude-context/blob/main/synchronizer.ts) precedes all pattern evaluation and cannot be overridden by configuration. The design prioritizes security and performance by excluding version control metadata, environment files, and editor state by default.

### How does Claude Context handle nested directory patterns?

The matching algorithm implements **parent-directory cascade checking** in step 5 of `shouldIgnore()`. When evaluating a path like [`node_modules/lodash/index.js`](https://github.com/zilliztech/claude-context/blob/main/node_modules/lodash/index.js), the algorithm checks each parent segment (`node_modules`, `node_modules/lodash`) against directory-only patterns (those ending with `/`). If any parent matches, the entire subtree is excluded. This ensures patterns like `node_modules/` correctly exclude all nested content without requiring explicit `**` syntax.