# DesktopCommanderMCP bootstrap.ts Module: Purpose and Import Order Requirements

> Discover the purpose of bootstrap.ts in DesktopCommanderMCP. Learn how to set UV_THREADPOOL_SIZE to 16, preventing thread starvation and hangs during heavy I/O operations.

- Repository: [Eduard Ruzga/DesktopCommanderMCP](https://github.com/wonderwhy-er/DesktopCommanderMCP)
- Tags: internals
- Published: 2026-08-06

---

**The [`bootstrap.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/bootstrap.ts) module sets the `UV_THREADPOOL_SIZE` environment variable to 16 before any asynchronous file operations initialize Node.js's libuv thread pool, preventing thread starvation and multi-minute hangs during heavy parallel I/O.**

The [`bootstrap.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/bootstrap.ts) file serves as a critical entry-point initializer in the wonderwhy-er/DesktopCommanderMCP repository. This tiny module ensures that Node.js's libuv thread pool is properly sized before any file system work begins, directly impacting the performance and reliability of the CLI tool under concurrent load.

## Why Libuv Thread Pool Size Matters

All asynchronous file operations in Node.js—reading, writing, editing files, and persisting configuration—execute on libuv's internal thread pool. By default, Node.js initializes this pool with only **4 worker threads**.

When multiple agents perform slow I/O operations simultaneously (such as accessing cloud-synced drives), these four threads can become blocked for minutes waiting for the operating system to return. Because a blocked thread holds its slot until completion, additional file system requests queue up and experience severe latency. This manifested as multi-minute hangs under heavy parallel load, as noted in the comments within [[`src/bootstrap.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/bootstrap.ts)](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/bootstrap.ts).

## What bootstrap.ts Does

The module performs three critical functions:

1. **Defines a default size**: Sets `DEFAULT_THREADPOOL_SIZE` to 16.
2. **Conditionally sets the environment variable**: Assigns `process.env.UV_THREADPOOL_SIZE` only if the user has not already supplied a value.
3. **Executes early**: Runs before any code triggers thread-pool work.

```typescript
// src/bootstrap.ts
const DEFAULT_THREADPOOL_SIZE = 16;

if (!process.env.UV_THREADPOOL_SIZE) {
  process.env.UV_THREADPOOL_SIZE = String(DEFAULT_THREADPOOL_SIZE);
}

```

Because libuv reads `UV_THREADPOOL_SIZE` exactly once when creating the thread pool, this assignment must occur before any asynchronous file operation initializes the pool.

## Import Order Requirements and Why Timing Matters

The entry script [[`src/index.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/index.ts)](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/index.ts) explicitly imports [`bootstrap.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/bootstrap.ts) before any other modules:

```typescript
// src/index.ts
import './bootstrap.js';               // ← MUST be first
import { FilteredStdioServerTransport } from './custom-stdio.js';
// ... other imports

```

The inline comment states: *"MUST be first: raises the libuv threadpool size before any fs work is submitted."*

If any other module performing file operations were imported first, the thread pool would initialize with the default size of 4. Subsequent changes to `UV_THREADPOOL_SIZE` would have no effect because libuv never re-reads this variable. Therefore, **the bootstrap module must be the very first import** in the runtime execution chain.

### Incorrect Import Order (Anti-pattern)

```typescript
// ❌ Wrong order – file operation triggers pool creation before bootstrap
import { readFile } from 'fs/promises';   // <-- triggers thread-pool creation
import './bootstrap.js';                  // <-- too late, has no effect

```

In this scenario, the pool remains locked at 4 threads regardless of the bootstrap module's settings.

## Customizing the Thread Pool Size

Advanced users can override the default by setting the environment variable before launching the CLI:

```bash
UV_THREADPOOL_SIZE=32 npx desktop-commander-mcp

```

When [`bootstrap.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/bootstrap.ts) detects an existing `UV_THREADPOOL_SIZE` value, it respects the user-provided setting and does not overwrite it. This allows fine-tuning based on specific hardware capabilities or workload requirements.

## Verifying Configuration at Runtime

You can confirm the effective thread pool size in any downstream module by logging the environment variable:

```typescript
// In any later module (e.g., src/server.ts)
console.log('Threadpool size:', process.env.UV_THREADPOOL_SIZE);
// Expected output: "Threadpool size: 16" (or user-provided value)

```

## Summary

- The [`bootstrap.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/bootstrap.ts) module prevents I/O bottlenecks by sizing Node.js's libuv thread pool before initialization.
- It sets `UV_THREADPOOL_SIZE` to **16** by default, quadrupling the standard 4-thread pool.
- **Import order is critical**: [`bootstrap.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/bootstrap.ts) must be imported first in [`src/index.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/index.ts) before any file system operations trigger thread-pool creation.
- Users can override the default by setting `UV_THREADPOOL_SIZE` before launching the application.
- Once the thread pool initializes, changing the environment variable has no effect until the process restarts.

## Frequently Asked Questions

### What happens if bootstrap.ts is not imported first?

If [`bootstrap.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/bootstrap.ts) is not the first import, any preceding module that performs asynchronous file operations will trigger the creation of libuv's thread pool with the default 4 threads. The subsequent [`bootstrap.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/bootstrap.ts) import will set the environment variable, but libuv ignores it because the pool already exists. This leaves the application vulnerable to thread starvation and multi-minute hangs under heavy I/O load.

### Can I change the thread pool size without modifying the source code?

Yes. Export the `UV_THREADPOOL_SIZE` environment variable before running the CLI command. For example: `UV_THREADPOOL_SIZE=64 npx desktop-commander-mcp`. The [`bootstrap.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/bootstrap.ts) module detects existing values and preserves them, allowing you to customize the pool size based on your system's CPU count and I/O patterns.

### Why does DesktopCommanderMCP use 16 threads instead of the default 4?

The default 4-thread pool proved insufficient for DesktopCommanderMCP's use case, where multiple agents frequently perform parallel file operations on potentially slow storage (such as cloud-synced drives). The value 16 provides sufficient headroom to prevent queue buildup while remaining conservative enough to avoid excessive memory overhead on typical development machines.

### Does the bootstrap.ts module affect all DesktopCommanderMCP operations?

The module specifically affects all operations relying on Node.js's asynchronous file system APIs (such as `fs.readFile`, `fs.writeFile`, and file watching). It does not alter the behavior of synchronous file operations or CPU-bound tasks, but since DesktopCommanderMCP is primarily I/O-driven, proper thread-pool sizing benefits most of its core functionality.