Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallGitHub replaced the shared runtime behind Copilot CLI, Copilot app and Copilot SDK with Rust, porting it incrementally while the project continued to ship. In Stephen Toub’s GitHub Blog account, the completed runtime port comprised 832,378 lines of production Rust; AI agents helped with the work, but the migration still required extensive tests, human review and fixes for correctness and lifecycle regressions. The change was not a rewrite of every Copilot product, nor did port completion mean the runtime had been redesigned around Rust.
Why move a shared Copilot runtime away from Node.js?
The runtime began as TypeScript running on Node.js and V8, a sensible fit when the priority was to build a terminal application quickly. It later became a shared component used by the Copilot CLI, app and SDK, and by a wider range of GitHub, Microsoft and ecosystem products. For SDK consumers and services with tighter resource and density constraints, the runtime’s startup, memory and process costs mattered more.
Before the port, an SDK client started the CLI headlessly as a separate process and exchanged messages using bidirectional JSON-RPC over pipes or sockets. That arrangement meant launching Node/V8, managing an extra process and moving events and messages across a process boundary. Toub’s target was a native runtime that SDKs could embed through a C ABI, while retaining a server option for out-of-process hosting.
Rust was chosen to pursue lower overhead, native embedding, performance and scalability, and interoperability with six SDK languages. Toub also cites security and toolchain considerations. His framing was not that large TypeScript applications should generally be rewritten: “I didn’t set out to move to Rust, I set out to move away from Node.js and V8.”
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
#1 Best Overall
What the migration changed—and what it did not
The project joined two related efforts: separating terminal UI code from the runtime, and porting the runtime itself. Toub described the runtime port as complete, but said the CLI still called runtime internals in some places. Moving the CLI fully onto the SDK’s public surface remained ongoing. In other words, the Rust runtime was a completed translation, not the end of every boundary cleanup.
Nor was the completed port a Rust-first redesign. Toub characterized it as a behavior-preserving translation: Rust implementations still contained algorithms and structures shaped by the original TypeScript design. Further work was underway to improve builds and the developer loop, simplify translated structures, redesign around Rust ownership and concurrency, and pursue additional performance gains.
How GitHub replaced the runtime without a big-bang cutover
The team replaced components in place instead of switching the entire runtime at once or maintaining two full implementations in parallel. Each pull request replaced a TypeScript component with a thin shim into Rust, ran existing end-to-end tests, and deleted the replaced code. That made changes smaller to review and let the main branch continue to ship.
Rank #2
- Build the foundations. The team established the Rust workspace, toolchain, CI, build and code-generation setup, and language interop before porting substantial runtime behavior.
- Start with low-coupling code. The first ports were side-effect-free helpers. Work then moved toward components with more state and dependencies, leaving session orchestration until near the end.
- Bridge the languages temporarily. N-API let remaining TypeScript callers use components already ported to Rust. The seam peaked on August 3 at 2,019 internal N-API exports and 3,356 TypeScript call sites; Toub says the temporary internal seam was gone at completion.
- Validate each replacement and remove the old implementation. Existing end-to-end tests ran with each component change, rather than waiting for a final all-at-once cutover.
Toub reported runtime completion on August 21, 2026: 832,378 lines of production Rust and 468,689 lines of Rust unit tests, alongside 174,675 lines of TypeScript end-to-end tests. The separate Copilot SDK repository added approximately 130,000 end-to-end test lines across Node.js, Python, Go, C#, Rust and Java. These counts describe the scale of the implementation and test suites; line counts by themselves do not establish correctness.
Recommended Free Tools
Dependencies also had to change with the language. The post says approximately 60 npm dependencies used only by runtime code were removed, while some remained because the CLI still relied on them. For example, runtime uses of zod were replaced with serde, schemars and jsonschema; libraries for tokenization, ignore patterns, glob matching, diffs, HTML sanitization and keyring access were also replaced.
What the reported benchmarks show
Toub compared the C# SDK before and after the port against a deterministic localhost chat-completion server that returned a fixed, small response. The measurements exclude model inference and network latency. They capture client startup, process launch, session creation, event handling, persistence and teardown. Other changes also landed during the comparison period, so these are results for the delivered system, not an isolated test of Rust versus TypeScript.
Rank #3
| Workload | May 12 baseline | August 21, Rust out of process | August 21, Rust in process |
|---|---|---|---|
| Client, session and one turn | 5.25 s | 1.33 s | 292 ms |
| Resume a 32-turn session | 5.64 s | 1.52 s | 264 ms |
| Ten concurrent client lifecycles | 12.34 s | 4.18 s | 742 ms |
| 1,000 one-turn session lifecycles | 132.52 s | 22.53 s | 20.93 s |
For a separate workload of 100 concurrent pipelines, Toub reported throughput of 7.55 one-turn session lifecycles per second before the port, 57.45 with Rust out of process and 120.0 with Rust in process. A resource sample for that workload recorded 312 seconds of aggregate CPU for the earlier process tree and about 110 seconds for the Rust configurations. These figures apply to the specified workload and test setup; they are not a general speedup guarantee.
For a ten-client batch, the reported peak resident private memory added above baseline was 1,383 MB before the port, 247 MB with Rust out of process and 126 MB with Rust in process. Toub cautions that memory measurements are easy to misuse and vary by machine and workload, so these values should be read as measurements from that particular comparison.
Free tools Windows power users keep installed
One-click scans. No signup required.
Choosing in-process or out-of-process hosting
The port created two hosting choices rather than making every SDK consumer share the runtime’s process. Toub reported faster lifecycle times and lower memory in the tested in-process configuration, but said in-process entry points were opt-in while the team built confidence in sharing a process and failure boundary.
| Hosting choice | What it means | Trade-off to consider |
|---|---|---|
| In process | The SDK uses the native runtime within the client’s process. | It avoids the separate runtime process and its cross-process messaging, but shares a process and failure boundary with the host. |
| Out of process | The runtime is hosted separately and the client communicates with it. | It retains process separation, with the associated launch and communication costs. |
The benchmark results above are evidence for the tested workloads, not a universal answer about which mode a consumer should choose. The practical decision depends on the host’s latency, throughput and memory needs, deployment constraints, and appetite for process and failure isolation. The GitHub Copilot Rust SDK README also documents managed and in-process transport and packaging options; SDK implementation details can change over time.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.What went wrong in the port
By September 14, 2026, Toub said dozens of known regressions had been traced and fixed. Most were correctness problems, though some affected performance. He grouped recurring issues into several patterns:
- Incomplete migration: some behavior or dependencies had not been carried across as intended.
- State and lifetime handling: Rust required lifetimes and shared state to be represented explicitly, and lifecycle behavior regressed in some cases.
- Behavior-contract mismatches: a translation could compile and still differ from the behavior callers expected.
- Host-boundary errors: assumptions at the edges between runtime, SDK and host could fail when those components interacted.
- Incorrect test oracles: tests could miss a regression if their expected behavior was derived from the same faulty implementation being changed.
Toub said missing-feature regressions were usually associated with insufficient end-to-end coverage, with one exception, and acknowledged that additional issues might remain. That is why he called end-to-end tests “absolutely, unequivocally critical.” For agent-assisted work, the important point is not simply to generate more code: the tests need to check externally observable behavior independently of the implementation being ported.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Clear out junk files and repair common Windows errors3Fix the driver behind crashes, sound loss and screen glitchesWhat the project says about using agents for a large rewrite
Toub’s conclusion was that a rewrite of this size had not been affordable before agents. He estimated approximately $120,000 in token spending and roughly three weeks of developer time, using the share of pull requests as a rough proxy for time. Those are his estimates, not audited accounting or a reusable budget for another migration. He also emphasized that this was not a solo effort: teammates contributed substantially to N-API, five SDK FFI implementations, packaging, build-time improvements, caching and review.
The practical lessons he drew from the work are:
- Define the end state first. Be precise about which component is being replaced and what remains outside the scope; otherwise a port can be declared done while important boundaries are still unfinished.
- Build end-to-end coverage before translation. Tests should assert observable behavior, and their oracle should remain independent of the agent changing the implementation.
- Translate first, redesign second. A behavior-preserving port gives the team a way to separate language-migration risk from architectural-change risk. Redesign can follow once the replacement is established.
- Turn repeated mistakes into guardrails. When agents repeat an error, encode the correction in reusable instructions, checks or tooling rather than relying on the same review comment each time.
- Invest in the inner loop. Fast builds and tests help people and agents iterate, while incremental pull requests keep work reviewable and continuously testable.
The project’s own timeline illustrates that the agent was part of a larger engineering system: the team replaced code slice by slice, maintained tests, reviewed changes, fixed regressions and built language bridges and packaging. The result supports a narrower claim than “agents can safely rewrite any system”: for this shared runtime, GitHub used agent-assisted incremental translation alongside substantial human engineering and validation.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




