When Microsoft shipped the Azure CLI, or when Google chose TypeScript for Gemini CLI, the inevitable question surfaced in every forum: why TypeScript? Isn't it slow? The question itself reveals a misunderstanding worth unpacking fully.
TypeScript isn't chosen for CLIs because of its performance. It's chosen in spite of its performance not being best-in-class. And paradoxically, that's exactly what makes it the right call for many teams.
ποΈ The performance myth
Let's start with the most important point: TypeScript doesn't run. The code you write gets transpiled to plain JavaScript, which then executes on a runtime like Node.js (V8), Deno, or Bun. The end result at runtime is practically identical to writing JavaScript by hand.
If the goal were raw performance, the debate would be between Go, Rust, > and C++. TypeScript wouldn't even be in the conversation.
And yet, it is in the conversation. Constantly. Because performance is rarely the real bottleneck in a client tool. What actually is: the time it takes a team to build it, maintain it, and evolve it over years.
π The real argument: sustained productivity
TypeScript introduces static typing without giving up JavaScript's dynamism. For a CLI of any real complexity β with subcommands, flags, plugins, and external API calls β that translates into something very concrete: the compiler catches bugs before the user does.
Autocomplete actually works. Refactors don't turn into archaeological expeditions. Contracts between modules are written in the code itself, not in a Confluence doc nobody updates. As the project grows, that difference compounds.
The ecosystem as a competitive advantage
Perhaps the most underrated argument is the ecosystem. Node.js has been the backbone of the web for decades, and that has a very valuable side effect for people building CLI clients:
Everything you need already exists, is actively maintained, and works on Windows, Linux, and macOS without touching a single compiler flag. Libraries like commander, inquirer, chalk, or execa aren't experiments β they're battle-tested dependencies used across thousands of real projects.
Add to that the portability of distribution β a single npm install, or a standalone binary packaged with bun build or pkg β and you have an argument that's hard to dismiss when the goal is getting a client in front of users with as little friction as possible.
The team factor
There's one element benchmarks don't capture: the human cost. On a team where frontend and backend coexist, TypeScript allows sharing data models, validations, and HTTP clients between the web app and the CLI. Onboarding a new developer who already knows JS/TS takes hours, not weeks.
Companies like Microsoft or Google don't choose TypeScript because it's the most performant language available. They choose it because it shrinks the distance between an idea and a working client β and because that client can keep growing without breaking.
The verdict: why TypeScript wins (and why it doesn't)
π΄ Not for runtime performance
π’ Yes, for productivity and developer experience (DX)
π’ Yes, for a mature ecosystem and instant portability
π’ Yes, for long-term maintainability
π’ Yes, for reducing team cost and iteration speed
π So when should you not use TypeScript?
TypeScript isn't universal. It occupies a very specific sweet spot, and knowing when to leave it is just as important as knowing when to lean in.
Every language choice should start by honestly answering six questions before committing to anything:
- Ecosystem: Are there mature libraries for what you need?
- Portability: Does it work smoothly on Windows, Linux, and macOS?
- Performance: Do you need maximum speed or minimal resource usage?
- Distribution: Standalone binary, script, or npm/pip package?
- Team: What languages do your developers actually know well?
- Evolution: Will this client grow significantly in complexity over time?
A language map: who wins in each scenario
| Language | When to use it | Why not always |
|---|---|---|
| TypeScript | Interactive CLIs, evolving APIs, JS/TS teams, cross-platform distribution | Requires a runtime; not optimal for heavy computation |
| Go | Standalone binaries, infrastructure tooling, fast and simple CLIs | Rich interactivity takes more effort; more fragmented ecosystem |
| Rust | Performance-critical tools, intensive processing, memory safety requirements | Steep learning curve, slower development, costly builds |
| Python | Prototypes, automation scripts, AI/data integration | Distribution is painful, complex dependencies, runtime on the user's machine |
π A quick decision guide
- TypeScript β Interactive cross-platform CLI with external APIs and a JS/TS team.
- Go β Dependency-free binary anyone can run without installing anything.
- Rust β Maximum performance or memory safety; development cost is acceptable.
- Python β Quick prototype or internal tool where distribution doesn't matter.
"TypeScript isn't the best language for running code. It's one of the best for keeping software alive for years."

Top comments (0)