TechReaderDaily.com
TechReaderDaily
Live
Languages & Runtimes · TypeScript

TypeScript Eats the World While Its Runtimes Splinter

Node, Bun, and Deno are all converging on TypeScript as the standard for server-side JavaScript, a bet that accelerates adoption but creates fragmentation with hidden costs for developers.

Illustration comparing Bun and Deno JavaScript runtimes with their logos on a split background. dushkin.tech
In this article
  1. The Compiler That Changed the Calculus

On March 17, 2026, Bleeping Computer reported that the LeakNet ransomware gang had begun deploying a malware loader built on the open-source Deno runtime for JavaScript and TypeScript. The attackers were not exploiting a zero-day in Deno. They were using Deno exactly as its creators intended: as a fast, secure, cross-platform runtime that executes TypeScript out of the box. The technique, known as ClickFix, tricks users into running a malicious script that fetches and executes a Deno-based payload. Because Deno is a legitimate, signed binary, it slips past endpoint detection tools that would flag an unknown executable. A language ecosystem designed to make server-side scripting safer had become infrastructure for a criminal enterprise.

The LeakNet story is a vivid, uncomfortable data point in a larger narrative that has been building for three years. The JavaScript runtime landscape, once a comfortable monoculture centered on Node.js, has fractured into three serious contenders: Node.js itself, now in its sixteenth year and stewarded by the OpenJS Foundation; Deno, the security-forward runtime created by Node.js founder Ryan Dahl and now at version 2.0; and Bun, the Zig-written speed demon that compiles and runs TypeScript natively without a separate build step. All three are converging on TypeScript as their default language of expression. All three are competing for the same developer mindshare. And all three are learning that broad adoption brings consequences that no amount of careful API design can fully anticipate.

Deno turned four years old in May 2024, and the release of Deno 2.0 in October of that year marked a decisive strategic pivot. Where Deno 1.x had positioned itself as a clean break from Node, rejecting the node_modules directory, CommonJS modules, and the entire npm ecosystem in favor of URL-based imports and web-standard APIs, Deno 2.0 reversed course. InfoWorld reported at the time that the release was "fully compatible with existing Node.js projects, allowing developers to run their existing applications seamlessly." The deno binary learned to read package.json, resolve imports from node_modules, and run most npm packages without modification. The purity play was over. The pragmatism play had begun.

Deno 2.0 is fully compatible with existing Node.js projects, allowing developers to run their existing applications seamlessly while also taking advantage of Deno's modern, all-in-one toolchain., Deno Land announcement, as reported by InfoWorld, October 2024

That pragmatism turned Deno from an interesting experiment into a credible alternative for teams that wanted a single binary with a built-in linter, formatter, test runner, and TypeScript compiler, but could not afford to abandon their existing dependencies. It also made Deno legible to attackers in a way that Deno 1.x, with its deliberately smaller footprint and restricted I/O model, had not been. The irony is thick: Deno was conceived in part as a response to Node's security shortcomings, with a permissions system that requires explicit opt-in for file system access, network calls, and environment variable reads. Yet the LeakNet campaign demonstrates that a runtime designed for security can be repurposed as camouflage precisely because it is trusted.

Bun emerged from a different set of frustrations. First released in 2022 by Jarred Sumner, Bun was built in Zig and optimized for startup time, throughput, and developer experience. Its marquee feature was native TypeScript support: Bun could parse, type-check, and execute .ts files without a separate compilation step, eliminating the tsc or ts-node tax that had long been the least-loved part of the Node.js workflow. By mid-2025, Bun had matured enough to attract attention from platform vendors. In April 2026, InfoQ reported that Pulumi, the infrastructure-as-code platform, had added full Bun runtime support, with Birgitta Böckeler, a Distinguished Engineer at Pulumi, noting the integration in the company's release notes. When an infrastructure provisioning tool treats a runtime as a first-class target, the runtime has crossed a threshold of enterprise legitimacy.

Node.js, for its part, has not stood still. The 22.x LTS release, which entered long-term support in October 2024, brought native TypeScript support via the --experimental-strip-types flag, allowing Node to execute TypeScript source directly by stripping type annotations on the fly, the same approach Bun had popularized. The feature moved from experimental to stable in Node 23, which went LTS in mid-2025. Node's stewards were sending a clear signal: TypeScript is not a bolt-on or a third-party concern; it is a first-class citizen of the platform. The decision also narrowed the gap that Deno and Bun had exploited. If every runtime speaks TypeScript natively, the switching cost between them drops, and the competitive axis shifts from "which runtime supports my language" to "which runtime handles my workloads best."

The Compiler That Changed the Calculus

While the runtimes were jockeying for position, the TypeScript team itself was undertaking the most radical re-architecture in the language's history. In 2025, Microsoft announced a project to port the TypeScript compiler and language service from TypeScript to Go. The goal was not ideological purity but raw performance. The existing compiler, famously, is a recursive descent parser implemented in TypeScript, bootstrapped through itself, slow on large codebases, and a drag on editor responsiveness. The Go port, first previewed in Visual Studio 2026 Insiders builds in October 2025, promised a roughly 10x speedup on type-checking and compilation workloads. On April 21, 2026, Visual Studio Magazine reported that TypeScript 7.0 had entered beta, with Microsoft calling the compiler "production-ready for many day-to-day workflows and CI pipelines."

The Go port matters for the runtime story in ways that are not immediately obvious. TypeScript's compiler had always been a Node.js program. Every tsc --noEmit command, every editor language-service invocation, every CI pipeline that ran type-checking was an implicit vote of confidence in Node.js as the host environment. By moving the compiler to Go, Microsoft severed that implicit dependency. The new compiler ships as a native binary. It does not need Node, Deno, or Bun to run. It is faster on its own than any of them could make it. That architectural shift subtly repositions TypeScript from a Node-ecosystem citizen to a platform-independent tool, one that can be plugged into any editor, any build system, any CI runner, regardless of which JavaScript runtime that system happens to prefer.

The fragmentation of JavaScript runtimes is not inherently good or bad. It is expensive, and the costs fall unevenly. For package maintainers, the proliferation of runtimes means more CI matrices, more platform-specific bug reports, and more pressure to avoid runtime-specific APIs even when those APIs are genuinely better than the lowest-common-denominator alternative. For application developers, it means more decisions to make at project inception, each with long-term consequences for hiring, deployment, and the available library ecosystem. For security teams, as the LeakNet campaign makes plain, it means a larger attack surface: every runtime that can execute arbitrary TypeScript or JavaScript on a corporate endpoint is a potential loader for malicious code.

What makes the current moment distinct from earlier language wars is that the combatants are not, strictly speaking, fighting over different languages. They are fighting over different values expressed through the same language. Node represents stability, ecosystem breadth, and operational predictability; it is the runtime you choose when you want to hire from the largest possible talent pool and deploy to the widest range of platforms without surprises. Deno represents security, simplicity, and an integrated developer experience; it is the runtime you choose when you believe that a batteries-included standard library and a fine-grained permissions model reduce entire classes of operational risk. Bun represents speed above all else; it is the runtime you choose when cold-start latency and benchmark performance are the dominant constraints on your architecture.

Each of these values has a shadow. Node's stability is also its inertia; the platform is slow to ship breaking changes, which means legacy API surfaces accumulate and the core team carries a growing maintenance burden that few newcomers are willing to share. Deno's integrated toolchain is also a form of vendor lock-in: adopt Deno's linter, formatter, and test runner, and you are writing code that other runtimes can execute but that only Deno can fully support. Bun's speed is achieved partly through compatibility shortcuts; the runtime does not yet pass the full Node.js test suite, and edge cases in its TypeScript implementation can produce behavior that diverges from what tsc would have caught.

The TypeScript 7.0 beta adds a new dimension to these trade-offs. If the Go compiler catches type errors 10x faster than its predecessor, the argument for building TypeScript-native runtimes like Bun that include their own faster-but-less-complete type-checking implementations becomes harder to sustain. Why accept an incomplete type-checking experience when the official compiler is now fast enough to use in development? Conversely, if the Go compiler becomes the standard tool for production type-checking, runtimes that invested heavily in their own TypeScript implementations may find themselves maintaining parallel code paths that fewer and fewer users actually need.

Ryan Dahl has spoken publicly and repeatedly about the lessons he learned from Node.js, framing Deno as an attempt to correct mistakes that could not be fixed without breaking changes. In a 2024 talk at JSConf EU, he described the Node.js ecosystem's reliance on node_modules as "a design decision that made sense for 2010 and has cost the industry billions of engineering-hours since." The Deno 2.0 compatibility layer is, by that logic, a concession to the reality that no one runtime, no matter how thoughtfully designed, can dislodge an ecosystem with three million packages and fifteen years of accumulated tooling. The question Deno now faces is whether backward compatibility with Node.js will allow it to grow beyond its niche, or whether it will trap the project in a cycle of chasing a moving target, forever implementing Node APIs that were designed under constraints Deno explicitly rejected.

Bun's trajectory is different. It is building a platform, not just a runtime: the Bun binary includes a package manager, a bundler, a test runner, and a growing set of built-in modules for SQLite, S3, and HTTP serving. The vision is closer to what Go or Rust offer as a standard library experience, a single tool that does enough to be a project's entire development dependency. Pulumi's adoption of Bun as a supported runtime is a signal that the platform approach resonates with infrastructure teams who value reproducibility and fast cold starts. But it also raises a question about governance: Bun is, at time of writing, primarily the work of a single company, Oven, which has raised venture capital and must eventually demonstrate a return. The runtime's long-term roadmap is tied to Oven's business model in a way that Node's, governed by the OpenJS Foundation, is not.

The LeakNet ransomware gang, for all the damage it has caused, is also a strange kind of stress test for the Deno project. A runtime that can be used as a malware delivery vehicle is a runtime that works well enough to be worth abusing. The Deno team has not publicly responded to the LeakNet campaign in detail, and it is not obvious what they could do that would not also break legitimate use cases. A permissions prompt is only effective when the user understands what they are approving; ClickFix attacks work by manufacturing urgency that short-circuits that understanding. The security model that Deno pioneered remains valuable, but it is not a complete defense, and the runtime ecosystem as a whole is still learning how to think about abuse resistance as a first-class design constraint.

What happens next depends on how the three runtimes navigate the tension between differentiation and convergence. TypeScript 7.0's Go-based compiler will ship as stable by late 2026, decoupling the language from its reference runtime. Node.js will continue to deepen its native TypeScript support with each LTS release. Deno will ship incremental improvements to its Node compatibility layer while trying to keep its own identity distinct. Bun will chase performance numbers and enterprise adoption, aiming to become the default choice for new projects in the same way that Next.js became the default React framework. None of them can afford to ignore TypeScript, and none of them can afford to be second-best at running it. The language wars have not ended. They have just moved from syntax to substrate.

Read next

Progress 0% ≈ 10 min left
Subscribe Daily Brief

Get the Daily Brief
before your first meeting.

Five stories. Four minutes. Zero hot takes. Sent at 7:00 a.m. local time, every weekday.

No spam. Unsubscribe in one click.