Skip to content
Engineering

GitHub's Rust Migration: How AI Reshaped Copilot's Runtime

GitHub's Copilot runtime shifts from Node.js to Rust, cutting startup times from seconds to milliseconds. What this means for developers.

Topic
Engineering
Reading time
5 min
Length
1,065 words
Published
Oct 13, 2026
02:48 pm IST
In this article
  1. Why the Shift from Node.js to Rust Matters
  2. Implementing the New Runtime in Your Projects
  3. Limitations and Considerations
  4. AI's Role in the Migration
  5. Challenges in Identifying Behavioral Contracts
  6. Continuous Integration and Testing

GitHub recently took on a big move by changing the runtime for its Copilot CLI, app, and SDK from a TypeScript and Node.js base to Rust. It's a hefty switch, involving over 800,000 lines of production code, with AI lending a hand in the rewrite. This transition, covering about 14.5 weeks and 128 pull requests, was executed while GitHub kept releasing updates to users. The outcome? A major boost in performance—startup, session creation, and single-turn scenario times plummeted from 5.25 seconds to just 292 milliseconds.

Why the Shift from Node.js to Rust Matters

If you're dealing with production codebases, this migration by GitHub is a big deal. Moving to Rust comes with solid performance benefits. Although Node.js is popular and flexible, it can suffer from overhead because of its reliance on the V8 engine and JavaScript. By turning to Rust, GitHub fine-tuned the runtime for speed and efficiency, cutting the working set per client by roughly 100 MB. That's a big win in environments where managing resources and performance is critical.

This change also affects how applications interact with the runtime. Instead of relying on Node.js and V8, the Rust version can be directly embedded into host applications using a C ABI, all while allowing an out-of-process mode. This flexibility is a boon for developers integrating Copilot into various settings. Embedding the runtime directly can make deployment smoother and reduce dependencies, leading to potentially more stable and maintainable systems.

Implementing the New Runtime in Your Projects

If you're eyeing the new Rust-based runtime for your applications, here are some steps to get started:

  • Evaluate Current Dependencies: Look at your current setup to see how the Node.js and TypeScript-based runtime fits in. Spot places where the Rust-based runtime might give you performance boosts or make integration easier. Think about how you can use a C ABI to replace existing interprocess communication methods.
  • Plan for Transition: If you're deep into Node.js, think about how the Rust runtime could slot into your applications. This might mean reassessing build processes and deployment pipelines to fit the new runtime. Make sure your team familiarizes themselves with Rust's build system and tools like Cargo to handle dependencies and compilation effectively.
  • Test Thoroughly: Like any big shift, thorough testing is key. Use your existing end-to-end tests to check the new runtime, focusing on boundary behaviors, state management, and library semantics just like GitHub did. Adding more unit tests specifically for the new Rust code paths is also a good idea.
  • Monitor Performance: Once integrated, keep a keen eye on performance metrics to make sure you're getting the expected gains. This includes monitoring startup times, memory usage, and overall application responsiveness. Rust's built-in profiling tools or external monitoring solutions can offer insights into runtime performance.
  • Iterate and Refine: Post-migration, ongoing tweaks are important. Rust's ecosystem is always changing, so staying up-to-date with the latest libraries and best practices will help in maintaining performance and security.
fn main() {
    println!("Welcome to the new Rust-based Copilot runtime!");
    // Initialize and configure your application here
}

Limitations and Considerations

While the benefits are clear, the shift to Rust comes with its own set of challenges. GitHub's transition involved a complex play of AI-assisted code generation, gradual integration, and human review. AI can speed up development, but it also brings challenges in ensuring the stability and correctness of the final product. GitHub's experience highlights the need for human oversight to spot regressions and maintain stability at runtime boundaries.

Additionally, Rust, despite its performance edge, is a tougher nut to crack compared to JavaScript and TypeScript. Developers used to these languages might need to invest some time in getting comfortable with Rust’s syntax and paradigms. The strategy GitHub used—incremental replacement with temporary compatibility layers—might not work for every project, especially if the architecture isn’t modular. Projects with tightly interlinked components may find it hard to isolate parts for incremental replacement without heavy refactoring.

AI's Role in the Migration

AI was instrumental in GitHub's migration. AI agents created the bulk of the implementation, which was then tested and reviewed by humans. This method shows off AI's potential in massive refactoring projects but also stresses the need for rigorous validation to ensure AI-generated code hits quality marks. The AI-assisted process involved more than just code generation; it required the new code to mesh with existing systems, manage dependencies, and interface carefully.

Feedback from the community on this AI-driven migration highlighted the difficulties of verifying AI-generated code, especially concerning issues like cancellation, retries, and backpressure. These areas need thorough checks beyond just making sure the code compiles, to safeguard system integrity and performance. AI-generated code can sometimes miss subtle aspects of application logic that human developers understand well, making comprehensive testing and review processes essential.

Challenges in Identifying Behavioral Contracts

A big challenge during the migration was spotting undocumented behavioral contracts in the old system. These often pop up in long-standing codebases where assumptions have built up over time. Côme Redon, a senior solution engineer at Microsoft, noted how tricky these contracts can be to identify, which can lead to surprises when shifting to a new language or runtime.

To tackle this, GitHub gradually replaced TypeScript components with Rust, using a temporary N API for interoperability between the two. This allowed existing end-to-end tests to run the new code while keeping other pieces in TypeScript, ensuring continuity and stability through the transition.

Continuous Integration and Testing

Throughout the migration, GitHub kept a strong focus on continuous integration and testing. The compatibility layer hit 2,019 internal N API exports and 3,356 TypeScript call sites before being phased out. By August 21, the runtime included 832,378 lines of production Rust and 468,689 lines of Rust unit tests. This extensive testing framework was vital for maintaining runtime stability and performance during the move.

GitHub completed 4,478 direct cargo check runs, with a high completion rate of 87.1%. This success in the build and test cycles was crucial for quickly spotting and fixing regressions. The blend of automated testing and human review was key in ensuring the AI-generated code lived up to the necessary quality standards and behaved as expected.

If you're curious about runtime migrations and performance tweaks, check out our article on Grab's Storage Migration: Lower Latency and Cost with Aerospike. And for those working with JavaScript, our piece on Enhancing JavaScript Analysis: Leveraging Control Flow Graphs might give you some helpful insights.

Sources

Github Migrates Copilot Runtime to Rust with AI-Assisted Rewrite

Every claim above was checked against this source before publishing. The analysis, the code and the opinions are mine.

Frequently asked

Why did GitHub choose Rust for the Copilot runtime?

GitHub migrated to Rust for improved performance, reducing client startup and session times significantly, and to simplify integration by embedding the runtime directly into applications.

What challenges does an AI-assisted migration present?

AI-assisted migrations require thorough validation to ensure stability, particularly in areas like cancellation, retries, and backpressure, and rely heavily on human oversight.

How can developers integrate the new Rust-based runtime?

Developers should evaluate current dependencies, plan for the transition, test thoroughly, and monitor performance to effectively integrate the new runtime.

Deepak Kumar

Written by

Deepak Kumar

Sr Software Engineer at India Today Group | Aaj Tak · MERN Stack · Generative AI

I build production web applications and Generative AI systems, and I have spent most of nine years on the maintenance end of other people's architectural decisions. I write here about what those systems actually do once real traffic hits them. Hiring an AI engineer in India? Here is how I work.

Message me