Purpose of bootstrap.ts in DesktopCommanderMCP: Why It Must Be Imported Before File System Operations

The bootstrap.ts module configures Node.js's libuv thread-pool size before the pool initializes, preventing I/O bottlenecks when multiple agents perform parallel file operations.

DesktopCommanderMCP relies on intensive file system interactions—reading configuration, persisting history, and executing block edits across potentially slow or cloud-synced disks. The bootstrap.ts utility ensures these operations remain responsive by expanding the thread-pool from its default size before any work is submitted, establishing the necessary environment before file system modules load.

The libuv Thread-Pool Bottleneck

Node.js delegates blocking file system operations to libuv's thread pool. By default, this pool contains only four threads. When DesktopCommanderMCP agents trigger parallel reads and writes—especially on network-attached or synchronized storage—these four threads can saturate quickly, causing subsequent operations to queue for minutes.

How bootstrap.ts Solves the Problem

According to the DesktopCommanderMCP source code, the bootstrap module addresses this by setting the UV_THREADPOOL_SIZE environment variable before libuv initializes its pool.

Early Environment Variable Injection

In src/bootstrap.ts, lines 4–9 document the core issue: heavy parallel load exhausts the 4-thread default. Lines 12–15 outline the solution—increasing the pool size to 16 by default—while lines 20–22 implement the actual assignment:

// src/bootstrap.ts (lines 20-22)
if (!process.env.UV_THREADPOOL_SIZE) {
  process.env.UV_THREADPOOL_SIZE = '16';
}

Because libuv reads UV_THREADPOOL_SIZE only when the thread pool is first initialized (i.e., upon the first work submission), this assignment must occur prior to any import that triggers file system activity.

Import Order Requirements

The entry point src/index.ts must import bootstrap.ts as its first dependency. This guarantees the environment variable is in place before any file system utilities in src/fs/* (such as read_file or write_file) submit work to the pool:

// src/index.ts – must import bootstrap first
import "./bootstrap";           // 👈 ensures UV_THREADPOOL_SIZE is set early
import { readFile } from "./fs"; // subsequent fs work uses the enlarged pool

Configuration Options

Users can override the default thread-pool size without modifying source code. If UV_THREADPOOL_SIZE is already defined in the environment, bootstrap.ts preserves the user-defined value:


# .env or shell export

UV_THREADPOOL_SIZE=32   # bootstrap.ts will detect and respect this

This allows fine-tuning for specific hardware or workload characteristics without code changes.

Demonstrating the Impact

When bootstrap.ts is imported first, parallel file operations scale properly. The following pattern prevents the congestion that occurs with the 4-thread default:

import "./bootstrap";
import { readFile } from "fs/promises";

async function stressTest(paths: string[]) {
  // With 16+ threads available, Promise.all does not bottleneck on thread starvation
  await Promise.all(paths.map(p => readFile(p)));
}

Without the bootstrap import, this workload would stall as threads wait for slow disk I/O to complete.

Summary

  • bootstrap.ts sets process.env.UV_THREADPOOL_SIZE to 16 (unless user-overridden) before libuv initializes its thread pool.
  • The module must be imported first in src/index.ts because libuv reads the environment variable only once—at pool initialization time.
  • All file system operations in src/fs/* benefit from the increased concurrency, preventing hangs during parallel agent activity.
  • Users can customize pool size via the UV_THREADPOOL_SIZE environment variable without code modifications.

Frequently Asked Questions

What happens if I import bootstrap.ts after other modules?

If bootstrap.ts is imported after any module that triggers file system operations, libuv will have already initialized its thread pool with the default 4 threads. Subsequent changes to UV_THREADPOOL_SIZE have no effect, and the application may experience I/O bottlenecks under parallel load.

Can I change the thread-pool size without modifying bootstrap.ts?

Yes. bootstrap.ts checks for an existing UV_THREADPOOL_SIZE value before setting the default. Define the variable in your shell or .env file (e.g., UV_THREADPOOL_SIZE=32), and the bootstrap logic will preserve your custom value.

Does bootstrap.ts affect operations other than file system calls?

Yes. Any Node.js operation that uses libuv's thread pool—including DNS resolution and certain crypto operations—will utilize the expanded thread pool. However, DesktopCommanderMCP specifically targets file system performance with this configuration.

Is DesktopCommanderMCP the only project that needs this pattern?

While any Node.js application performing parallel file I/O can benefit from increasing UV_THREADPOOL_SIZE, DesktopCommanderMCP requires strict import ordering because its MCP (Model Context Protocol) architecture generates concurrent file access patterns that quickly exhaust the default 4-thread limit. Projects with lighter I/O loads may not notice the limitation.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →