Migrating the GitHub Copilot runtime to Rust, using Copilot
GitHub rewrote its Copilot agent runtime from TypeScript to over 800,000 lines of Rust, improving performance and enabling broader embedding across products while reducing overhead.
The GitHub Copilot agent runtime, which powers tools like the Copilot CLI, Copilot app, and SDK, was originally written in TypeScript on Node.js and V8. After rapid growth, the team decided to rewrite it in Rust to address performance and embedding challenges across multiple products. The migration resulted in more than 800,000 lines of production Rust code, replacing the previous TypeScript implementation. AI agents assisted in writing much of the code, with changes shipped incrementally through 128 pull requests rather than a single overhaul.
The rewrite targeted shared runtime needs across Microsoft, GitHub, and ecosystem solutions, where performance and reliability were critical. The new Rust runtime supports products like VS Code, Visual Studio, Copilot Code Review, and Copilot Studio, consolidating agentic capabilities into a single foundation. Previously, individual products maintained separate agent loops, but now they rely on the GitHub Copilot SDK to access the shared runtime, reducing duplication and improving consistency.
The TypeScript-based runtime faced limitations in environments requiring fast startup, low memory overhead, and server density, such as headless or embedded use cases. The original architecture tightly coupled the CLI’s terminal UI with the runtime, complicating programmatic access via the SDK. To enable SDK usage, the team layered the SDK on top of the CLI, spawning Node.js processes for each SDK consumer, which introduced significant overhead and reliability risks.
The shift to Rust addressed these issues by enabling embedding through a C ABI, reducing startup and steady-state overhead, and ensuring predictable resource use. The migration process revealed that the initial TypeScript codebase was larger than estimated, with approximately 430,000 lines passing through the port. The team prioritized Rust for its alignment with embedding requirements, though they noted that language choices should be application-specific rather than prescriptive.