# How Ignore Lists Prevent node_modules from Crossing the Sync Wire in Cloudflare Computer

> Learn how ignore lists prevent node_modules from syncing in Cloudflare Computer. Discover how they filter paths at the sync layer, keeping node_modules local to your container.

- Repository: [Cloudflare/computer](https://github.com/cloudflare/computer)
- Tags: internals
- Published: 2026-08-08

---

**Ignore lists filter filesystem paths at the synchronization layer before changes are serialized to the RPC stream, ensuring that directories matching patterns like `node_modules` never leave the container-side DOFS storage.**

Cloudflare Computer uses a **DOFS** (Distributed Object File System) runtime to synchronize filesystem changes between a container-side SQLite database and client **RPC** connections. To prevent unnecessary network overhead and third-party code leakage, the synchronization pipeline applies **ignore lists** that intercept and discard unwanted path segments before they can cross the sync wire.

## Default Ignore Patterns and Path Matching

The ignore mechanism starts with a hardcoded default that targets dependency directories.

### DEFAULT_IGNORE Definition

In [`packages/dofs/src/sync/ignore.ts`](https://github.com/cloudflare/computer/blob/main/packages/dofs/src/sync/ignore.ts), the system defines a default exclusion list:

```typescript
export const DEFAULT_IGNORE = ["node_modules"];

```

This array contains the literal segment `node_modules`, which the.sync engine uses as a baseline filter for all change operations.

### Segment-Based Matching Logic

The `isIgnored(path, patterns)` function—implemented in the same file—performs **whole-segment matching** rather than substring searches. It splits the path into its components and returns `true` if any segment exactly matches a pattern.

Because the match operates on whole segments, only paths containing the literal segment `node_modules` (for example, [`/project/node_modules/foo/index.js`](https://github.com/cloudflare/computer/blob/main//project/node_modules/foo/index.js)) trigger the ignore flag. This precision prevents false positives while ensuring comprehensive exclusion of nested dependency directories.

## Filtering During Change Coalescing

Before any change entries reach the network layer, the coalescing engine prunes ignored paths from the candidate set.

### The Coalesce Generator

In [`packages/dofs/src/sync/coalesce.ts`](https://github.com/cloudflare/computer/blob/main/packages/dofs/src/sync/coalesce.ts), the `coalesceChanges` generator applies the ignore list while building the change set:

```typescript
const ignore = options.ignore ?? [];
// ...
if (isIgnored(path, ignore)) continue;   // ← drop ignored paths

```

Both the live-mutation scan and the tombstone scan invoke `isIgnored`. If a path matches an ignore pattern, the function executes `continue`, bypassing the yield statement. Consequently, no `ChangeEntry` for that path is ever generated or emitted.

This early filtering occurs **before** changes are serialized, meaning ignored files never enter the async iterable that feeds the RPC response.

## Server-Side Default Enforcement

The RPC server ensures that the `node_modules` exclusion persists even when clients omit custom ignore configurations.

### Fallback Logic in the RPC Server

In [`packages/rpc/src/server.ts`](https://github.com/cloudflare/computer/blob/main/packages/rpc/src/server.ts), the `fetchChanges` handler implements fallback logic:

```typescript
const ignore =
    input.ignore ?? (this.options.ignore.length > 0 ? this.options.ignore : DEFAULT_IGNORE);

```

If the client request does not specify an `ignore` array, the server checks its own options. When those are also empty, it falls back to `DEFAULT_IGNORE` from the DOFS sync module. This guarantees that `node_modules` entries are dropped before streaming begins, regardless of client behavior.

## Practical Configuration Examples

You can interact with the ignore list when invoking the sync client or overriding defaults.

### Using Default Exclusions

When fetching changes without specifying ignores, the client automatically benefits from the server-side default:

```typescript
// Client fetching changes – default ignore ("node_modules") is applied
const { stream } = await client.fetchChanges({
  after: { rev: 0, path: null },   // start from beginning
  // omit `ignore` → server falls back to DEFAULT_IGNORE
});

```

### Customizing the Ignore List

To extend exclusions (for example, to also ignore `.git` directories), pass a custom array:

```typescript
// Overriding the ignore list to exclude both node_modules and .git
await client.fetchChanges({
  after: { rev: 0, path: null },
  ignore: ["node_modules", ".git"],
});

```

The client sends this array to the RPC server, which uses it in place of the default. However, if you wish to retain the `node_modules` exclusion while adding patterns, you must include `"node_modules"` explicitly in your custom array.

## Summary

- **Default protection**: The `DEFAULT_IGNORE` array in [`packages/dofs/src/sync/ignore.ts`](https://github.com/cloudflare/computer/blob/main/packages/dofs/src/sync/ignore.ts) contains `["node_modules"]` and applies automatically when no other ignore list is specified.
- **Segment matching**: The `isIgnored` function uses whole-segment comparison to identify paths containing `node_modules` anywhere in their hierarchy.
- **Early filtering**: The `coalesceChanges` generator in [`packages/dofs/src/sync/coalesce.ts`](https://github.com/cloudflare/computer/blob/main/packages/dofs/src/sync/coalesce.ts) drops ignored paths before yielding `ChangeEntry` objects, preventing them from entering the sync stream.
- **Server enforcement**: The RPC server in [`packages/rpc/src/server.ts`](https://github.com/cloudflare/computer/blob/main/packages/rpc/src/server.ts) falls back to `DEFAULT_IGNORE` when clients omit the parameter, ensuring `node_modules` never crosses the wire by default.

## Frequently Asked Questions

### How does Cloudflare Computer ensure node_modules never syncs accidentally?

The system employs defense in depth. First, the `isIgnored` utility performs segment-based matching to catch any path containing `node_modules`. Second, the `coalesceChanges` generator filters these paths before emission. Third, the RPC server defaults to `DEFAULT_IGNORE` when clients provide no explicit ignore list, according to the implementation in [`packages/rpc/src/server.ts`](https://github.com/cloudflare/computer/blob/main/packages/rpc/src/server.ts).

### Can I sync node_modules if I need to?

Yes. When calling `client.fetchChanges()`, you can override the default by providing an explicit `ignore` array that omits `"node_modules"`. However, you must be deliberate about this, as the server-side fallback logic only applies when the `ignore` parameter is undefined—sending an empty array `[]` will effectively disable all ignore patterns, including the `node_modules` default.

### What is the performance impact of the ignore list?

The impact is negligible. The `isIgnored` check runs during the coalescing phase in [`packages/dofs/src/sync/coalesce.ts`](https://github.com/cloudflare/computer/blob/main/packages/dofs/src/sync/coalesce.ts), which operates on in-memory path strings before database cursors generate the final change set. Because it prevents large directory trees (often containing tens of thousands of files) from being serialized and transmitted over RPC, the ignore list significantly improves sync performance and reduces bandwidth consumption.

### Does the ignore list support glob patterns or only exact segment matches?

As implemented in [`packages/dofs/src/sync/ignore.ts`](https://github.com/cloudflare/computer/blob/main/packages/dofs/src/sync/ignore.ts), the current `isIgnored` function performs exact segment matching only. It splits paths by directory separators and checks for equality against the pattern strings. Glob patterns like `*.log` or `build/**` are not supported in the current implementation; patterns must match an entire path segment exactly.