The headline number — more than 800,000 lines of runtime code moved from TypeScript and Node.js to Rust in roughly 14.5 weeks — will be in somebody's slide deck by the end of the week, usually under a heading about how AI changes the economics of legacy modernisation. It does, a bit. But the throughput is the least transferable part of the story. What made that pace survivable was the surrounding engineering discipline: an incremental migration behind an N-API boundary, automated testing, human review on every change, and 128 pull requests landed while the product kept shipping.

Strip the AI out of that sentence and you are left with the classic recipe for a safe large-scale rewrite. Add the AI back in and you have the same recipe running faster. That distinction matters enormously if you are about to be asked why your own modernisation programme is in its third year.

A rewrite is only as safe as its oracle

The hard problem in any port is not writing the new code. It is knowing that the new code behaves identically to the old code for every input anyone cares about, including the inputs nobody documented. Machine-generated code makes writing cheap, which means the bottleneck moves entirely onto verification. If your definition of correct is a human reading a diff and nodding, you have not made the work faster — you have made it faster to produce plausible-looking defects.

What a project like this needs is an oracle: a suite that can tell you, mechanically and repeatedly, whether old and new agree. Characterisation tests, differential runs of both implementations against recorded traffic, property-based tests on the gnarly parsing and encoding paths. Most line-of-business estates do not have that. They have a smoke test, a UAT spreadsheet and a release weekend. An AI-assisted rewrite into a codebase like that isn't 14.5 weeks of progress — it's 14.5 weeks of unverified change, which is considerably worse than no change at all.

The interop seam is the design decision

N-API interoperability is quietly the most important architectural choice in the whole exercise. It lets you replace one module at a time, keep the rest of the system on the old runtime, and ship continuously rather than disappearing for a year and reappearing with a big bang cutover. It is the strangler pattern with a native binding as the seam.

The equivalent question for your own estate is: where could you put a stable, well-typed boundary that lets new and old coexist in production? If the answer is nowhere — because the data access, business logic and presentation are interleaved across the whole codebase — then your first programme of work isn't modernisation, it's carving out that seam. No amount of code generation shortcuts that. The seam is also what gives you a rollback story, and the ability to roll back one module is worth more than any velocity metric.

128 pull requests means review is the constraint

Averaged over the period, that is roughly nine or ten pull requests a week against a runtime that millions of developers depend on, every one of them needing a competent human to look at it. That is the real cost centre. Generation is cheap and getting cheaper; attention is not.

This is where I'd push back on most internal business cases I see described. They model the savings on developer hours spent typing and ignore that the reviewing population is the same small group of people who already hold all the domain knowledge, run the incidents and sign off the changes. Flood them with machine-authored diffs and review quality degrades in exactly the way you would expect — approvals get faster and less thorough, and the defects that slip through are the subtle semantic ones that tests written by the same tooling were never going to catch.

What changes on the operations side when Node becomes native

Swapping a managed runtime for compiled native code is not a neutral event for the people who run the platform. A few things reliably shift, and they land on infrastructure and security teams rather than on the developers who made the decision:

  • Packaging and distribution: you now ship platform-specific binaries rather than portable JavaScript. That means a build matrix, and it means code signing on every target platform.
  • Endpoint controls: new unsigned or newly-signed native binaries appearing on developer machines are exactly what application control and EDR policies are tuned to notice. Allow-listing, reputation and WDAC-style policies all need updating before rollout, not after the first wave of blocked installs.
  • Supply chain evidence: your SBOM tooling, dependency scanning and vulnerability feeds were pointed at npm. Crate dependencies need the same coverage, and the patching workflow for a compiled artefact is a rebuild-and-redeploy, not a transitive version bump.
  • Diagnostics: stack traces, crash dumps and profiling all look different. Whatever runbook your support team uses to triage a hung process needs rewriting for the new world.

None of this is an argument against the move. It is an argument for involving the people who own those controls at design time, because a successful rewrite that gets blocked by application control policy on day one is still an outage.

The conditions GitHub had, and you probably don't

Before this gets quoted at you as a benchmark, note the preconditions. A single product with a single owning team. Deep familiarity with the existing code. A continuous delivery pipeline that can ship small increments safely. Authority to change the architecture without a cross-departmental change board. A test estate good enough to trust. Remove any one of those and the timeline stretches; remove three and the approach stops being viable regardless of how good the tooling is.

[AUTHOR: add a real example from your own work here — a modernisation effort where the missing precondition, not the coding effort, set the pace.]

What to take from it

My view is that the useful lesson is inverted from the way it will be reported. This isn't evidence that AI can rewrite your legacy estate. It is evidence that teams with excellent testing, a clean interop boundary and real review capacity can now go considerably faster than before — and that everyone else has just been handed a much more efficient way to generate technical debt. The investment that unlocks the speed is the boring one: characterisation tests, a seam you can deploy across, and enough senior attention to review what comes out the other end.

If you want to use this story internally, use it as a specification for the capabilities you'd need first, not as a delivery estimate.

Source: Github Migrates Copilot Runtime to Rust with AI-Assisted Rewrite