# How code-server Integrates with VS Code's IPC Mechanism via the Session Socket

> Discover how code-server integrates with VS Code IPC using the session socket. Learn how it finds and reuses VS Code instances for native compatibility.

- Repository: [Coder/code-server](https://github.com/coder/code-server)
- Tags: internals
- Published: 2026-03-01

---

**code-server implements an HTTP-over-Unix-socket IPC layer (`EditorSessionManagerServer`) to discover and reuse existing VS Code instances, checking `VSCODE_IPC_HOOK_CLI` for native compatibility before querying the session socket registry.**

The **code-server** project enables VS Code to run in the browser by bridging local and remote development environments. Understanding how it integrates with VS Code's IPC mechanism via the session socket reveals how the tool prevents duplicate instances, routes workspace requests, and maintains compatibility with native VS Code child process communication.

## Architecture of the code-server VS Code IPC Session Socket

The integration centers on a Unix domain socket that implements a minimal HTTP server, allowing process-to-process discovery without network overhead.

### EditorSessionManagerServer

Located in [`src/node/vscodeSocket.ts`](https://github.com/coder/code-server/blob/main/src/node/vscodeSocket.ts), the **EditorSessionManagerServer** is an Express application bound to a Unix socket. It maintains an in-memory `Map<string, EditorSessionEntry>` registry and exposes three endpoints:

- `GET /session` – Accepts a `filePath` query parameter and returns the socket path of an existing instance handling that resource
- `POST /add-session` – Registers a new workspace-to-socket mapping via `AddSessionRequest`
- `POST /delete-session` – Removes entries during shutdown

The server listens on a path specified by `--session-socket` or a default temporary location, creating the bridge for VS Code IPC integration.

### EditorSessionManagerClient

The **EditorSessionManagerClient** (also in [`src/node/vscodeSocket.ts`](https://github.com/coder/code-server/blob/main/src/node/vscodeSocket.ts)) provides the consumer-side API. It serializes requests over the Unix socket using Node.js net modules, exposing:

- `canConnect()` – Verifies the session manager is reachable
- `getConnectedSocketPath(filePath)` – Queries `/session` to find existing handlers
- `addSession(entry)` – POSTs to `/add-session` to register new instances

This client enables both the code-server CLI and external tooling to interact with the IPC mechanism.

## How code-server Routes Requests Through the Session Socket

When you launch code-server, the CLI must decide whether to spawn a new instance or reuse an existing one. This decision logic in [`src/node/cli.ts`](https://github.com/coder/code-server/blob/main/src/node/cli.ts) relies on the session socket IPC mechanism.

### Checking for Existing Instances

The `shouldOpenInExistingInstance` function implements a dual discovery strategy:

1. **Native VS Code IPC Check**: If `VSCODE_IPC_HOOK_CLI` exists in the environment, the function returns that path immediately. This environment variable is set by VS Code when spawning child processes, ensuring code-server can delegate to an already-running desktop instance.

2. **Session Socket Query**: If the environment variable is absent, the function instantiates `EditorSessionManagerClient` and calls `getConnectedSocketPath(filePath)`. This sends a `GET /session` request to the Unix socket server, which searches its registry for an entry matching the requested workspace or file.

### Validating Socket Liveness

Before returning a candidate socket path, code-server validates that the target process is still alive. The `canConnect` utility in [`src/node/util.ts`](https://github.com/coder/code-server/blob/main/src/node/util.ts) attempts a net connection to the socket. If the connection fails, the **EditorSessionManagerServer** removes the stale entry from its in-memory map and continues searching. This automatic pruning prevents connection attempts to defunct processes while maintaining an accurate registry of active instances.

### Registering New Sessions

When no existing instance handles the requested resource, the CLI proceeds to spawn a new code-server process. After initialization, the new instance calls `addSession()` on the **EditorSessionManagerClient**, sending a `POST /add-session` request to register its workspace-to-socket mapping. This registration ensures that subsequent launches targeting the same workspace will discover and reuse this instance rather than spawning duplicates.

## Practical Example: Interacting with the Session Socket

You can interact directly with code-server's IPC mechanism using the `EditorSessionManagerClient` from your own Node.js scripts:

```typescript
import { EditorSessionManagerClient } from "./src/node/vscodeSocket";
import * as path from "path";

// Path to the session socket (the same one passed to code-server via --session-socket)
const sessionSocket = path.join("/tmp", "code-server-session.sock");

// Initialize the client
const client = new EditorSessionManagerClient(sessionSocket);

// 1. Check if the session manager is reachable
const isAlive = await client.canConnect();
console.log("Session manager active:", isAlive);

// 2. Register a new editor session (e.g., after starting a workspace)
await client.addSession({
  entry: {
    workspace: {
      id: "my-workspace",
      folders: [{ uri: { path: "/home/user/project" } }],
    },
    socketPath: "/tmp/vscode-ipc-12345.sock",
  },
});

// 3. Query for an existing session handling a specific file
const existingSocket = await client.getConnectedSocketPath("/home/user/project/file.ts");
if (existingSocket) {
  console.log("Reuse existing instance:", existingSocket);
} else {
  console.log("No active session found – start new server");
}

```

This example demonstrates how external tooling can leverage code-server's VS Code IPC integration to discover running instances and avoid port conflicts or duplicate workspace servers.

## Key Source Files for VS Code IPC Integration

Understanding the session socket implementation requires familiarity with these specific files in the code-server repository:

- **[`src/node/vscodeSocket.ts`](https://github.com/coder/code-server/blob/main/src/node/vscodeSocket.ts)** – Contains the **EditorSessionManagerServer** and **EditorSessionManagerClient** implementations, including the HTTP-over-socket routing logic for `/session`, `/add-session`, and `/delete-session` endpoints.

- **[`src/node/cli.ts`](https://github.com/coder/code-server/blob/main/src/node/cli.ts)** – Houses the `shouldOpenInExistingInstance` function that orchestrates the decision between reusing an existing VS Code instance (via `VSCODE_IPC_HOOK_CLI`) or querying the session socket for an available code-server instance.

- **[`src/node/util.ts`](https://github.com/coder/code-server/blob/main/src/node/util.ts)** – Provides the `canConnect` utility function used to validate socket liveness before returning paths from the session manager registry.

- **[`src/node/wsRouter.ts`](https://github.com/coder/code-server/blob/main/src/node/wsRouter.ts)** – Implements WebSocket upgrade handling that works alongside the session socket infrastructure, managing the main server transport layer.

- **[`src/node/socket.ts`](https://github.com/coder/code-server/blob/main/src/node/socket.ts)** – Contains TLS socket proxy implementations that complement the session socket when encrypted connections are required for the main server.

## Summary

The code-server project implements a sophisticated IPC mechanism that bridges browser-based VS Code instances with native VS Code's communication patterns:

- **HTTP-over-Unix-socket protocol** – The **EditorSessionManagerServer** exposes REST-like endpoints (`/session`, `/add-session`, `/delete-session`) over a Unix domain socket, enabling process-to-process discovery without network overhead.

- **Dual discovery strategy** – The CLI checks `VSCODE_IPC_HOOK_CLI` for native VS Code compatibility first, then falls back to the session socket registry to find existing code-server instances handling the requested workspace.

- **Automatic lifecycle management** – Dead sockets are pruned automatically via the `canConnect` probe, ensuring the registry only contains reachable instances and preventing connection attempts to stale processes.

- **Reusable client API** – The **EditorSessionManagerClient** provides a TypeScript interface for querying and registering sessions, enabling custom tooling to integrate with code-server's instance discovery mechanism.

## Frequently Asked Questions

### How does code-server handle the VSCODE_IPC_HOOK_CLI environment variable?

When `VSCODE_IPC_HOOK_CLI` is present in the environment, code-server treats it as a direct pointer to an existing VS Code IPC socket. The `shouldOpenInExistingInstance` function in [`src/node/cli.ts`](https://github.com/coder/code-server/blob/main/src/node/cli.ts) checks this variable before querying the session socket, ensuring compatibility with VS Code's native child-process communication mechanism and allowing code-server to delegate requests to an already-running desktop VS Code instance.

### What happens if the session socket points to a dead process?

Before returning a socket path from the registry, code-server validates liveness using the `canConnect` utility in [`src/node/util.ts`](https://github.com/coder/code-server/blob/main/src/node/util.ts). This function attempts a net connection to the candidate socket; if the connection fails, the **EditorSessionManagerServer** removes the stale entry from its in-memory map and continues searching for a valid match. This automatic pruning prevents connection attempts to defunct processes while maintaining an accurate registry of active instances.

### Can I query the session socket from external tools?

Yes, the **EditorSessionManagerClient** class in [`src/node/vscodeSocket.ts`](https://github.com/coder/code-server/blob/main/src/node/vscodeSocket.ts) provides a public TypeScript API for interacting with the session socket. You can instantiate the client with the socket path and call methods like `canConnect()`, `getConnectedSocketPath(filePath)`, and `addSession(entry)` to check manager status, discover existing instances handling specific files, or register new sessions from custom automation scripts or external tooling.

### How does code-server decide between reusing an instance versus starting a new server?

The decision logic resides in `shouldOpenInExistingInstance` within [`src/node/cli.ts`](https://github.com/coder/code-server/blob/main/src/node/cli.ts). The function first checks for `VSCODE_IPC_HOOK_CLI` to see if VS Code spawned code-server as a child process. If absent, it creates an **EditorSessionManagerClient** and queries the session socket via `getConnectedSocketPath` to find an existing code-server instance handling the requested workspace. Only when both checks return null does the CLI proceed to spawn a new server instance.