A bear playing hopscotch

The TypeScript vs JavaScript War is Dumb

There’s been a lot of drama over TypeScript lately. Some flamewars, some GitHub comment trolling, some very angry tweets. Many stem from a very public decision by DHH (David Heinemeier Hansson, founder of Ruby on Rails) to drop TypeScript from Turbo 8 alongside his later accusation of the open source community’s hooliganism.

Like many developers, we like TypeScript. Love it, honestly. All of our frontend libraries (except one) are written in TypeScript. Now, we don’t use TypeScript for our backend; we’re big on security and performance, which pushed us to chose Rust over Node for our critical infrastructure. That’s a discussion for another day—but point being, we’re pretty damn type-pilled.

Unfortunately, like most online debates, the TS vs JS arguments are centered on the comparison of extremes. They lack nuance. Most pieces take one of two attitudes:

  1. Why do you hate type safety, you type-hating-dummy!
  2. Or, how dare you disrespect JavaScript’s dynamic nature?

Extremism aside, we do think this debate is worth having. There is a crude equation of determining TypeScript’s worthiness: Time Saved by TS - Time Implementing TS. These two variables are exacerbated under various conditions. For a standard React application that’ll only grow in size and complexity, the time spent debugging JS errors often sharply outweighs the set-up and maintenance costs. For a tiny library that expects limited growth, a simple JavaScript app may be ideal.

Let’s dive into this equation in detail.

How does TypeScript save time

Let’s start with the easy positives. TypeScript offers some enormous benefits … enormous enough for some developers to have a ride-or-die attitude about using it.

Safety First!

TypeScript extends type-safety to JavaScript. It makes JavaScript less error-prone. By enforcing strongly-typed code, TypeScript prevents certain runtime errors from happening before code is even executed. This includes type-mismatch errors (e.g. Function A expects a string) and poor logic (e.g. X might be undefined and will fault here). Of course, TypeScript isn’t designed to prevent all errors. Plenty of array bounds errors will happen. It just removes “silly” mistakes.

But that is just the Dictionary-benefit of TypeScript. If you walk around San Francisco with a podcast mic, you’ll learn the real reason about why devs love TypeScript.

IDE Superpowers

Notably, TypeScript makes IDEs 10x more powerful. IDE—TypeScript integrations practically make TypeScript a documentation tool. TypeScript makes it easy to understand foreign library code by easily seeing input and output types. At times, TypeScript makes it possible to literally skip documentation READMEs.

We’re speaking from experience here. Oso has SDKs, including a Node SDK with provided types. In the past, our implementation of TypeScript was only half-decent; clients would write wrappers around Oso’s SDK to take better advantage of our library. We learned from this and shipped an ironclad dynamic TypeScript SDK, where users can generate config-aware types based on their Oso Configuration. These customized types will give explicit instant feedback on what ways an Oso user can invoke our API. (We explicitly took inspiration from Prisma’s dynamic-types design.)

The weaknesses of TypeScript

The critics of TypeScript don’t hate types. They just lament the struggle of implementing them.

There’s a line from DHH that best captures this sentiment.

Things that should be easy become hard, and things that are hard become any. — DHH, on why Turbo 8 is dropping TypeScript

It’s not just him. Ryan Carniato, the creator of Solid.js, also posted a similar piece about TypeScript in 2021. He makes an interesting point that CoffeeScript—a mostly extinct language that compiles pseudo-code-like representation of JavaScript into JavaScript—is the exact opposite of TypeScript. Some arbitrary 100 line code snippet in JavaScript would be logically equivalent to 30 lines in CoffeeScript … and about 200 lines in TypeScript. Turbo 8’s TypeScript-dropping PR, for instance, shedded 800 lines of code.

Carniato isn’t not wrong. TypeScript does a decent job inferring types, but that’s limited to mostly number and boolean situations. We’ve definitely seen files where the local type declarations were more lines of code than the actual logic.

Libraries’ equation is more skewed

Things get more interesting when it comes to libraries. Because libraries typically need to support a wide variety of inputs, their type complexity can exponentially grow relative to standard applications. Accordingly, so does the time needed to implement TypeScript scales, and the equation skews against it.

At the same time, one of the most requested features for libraries is support for types. Library code, unlike app code, is a public good. So when the public is calling for a feature, the issue becomes particularly contentious. Library users want good types, but library authors hate spending 80% of their time maintaining types. (Notably, these are primary authors, as many external contributors to Turbo 8 such as Marco Roth argued that TypeScript helped them make contributing easier).

Taking a step back, the calls for banishing TypeScript mostly come from library authors. The calls for TypeScript hails from basically everybody else. In short, users enjoy the benefit, library authors take the burden. Perhaps that’s just user feedback in action, but the split is worth observing because it underscores why the issue is so polarizing.

Remember, TypeScript is not a philosophy

TypeScript is not philosophy. It’s a language and a tool that was designed to be a subset of JavaScript—it literally interfaces 1:1 with JavaScript files and compiles to JavaScript before runtime. TypeScript’s end goal was to **improve code safety, not to shame the use of any and @ts-ignore when practically necessary. TypeScript—unlike other strongly-typed JavaScript-compiling languages like Rescript—included these tools to accommodate realistic frontend development. In the end, we are all trying to build safe applications at a reasonable pace. There’s no shame in striking the right balance.

A Closing Thought

Like many other developers, we think the TypeScript vs JavaScript flame war is more smoke than real. We are advocates for TypeScript, but would love a community that has a bit more empathy for library authors. More concretely, if there was more openness to generic types used in tricky places (e.g. any and unknown), we suspect there’d also be more openness to TypeScript, too. TypeScript is a tool—an excellent one. Not a dogma. Let’s remember that, and we’ll have a better compromise.

Want us to remind you?
We'll email you before the event with a friendly reminder.

Write your first policy