New Dec 30, 2024

TypeScript without Build Tools

More Front-end Bloggers All from Frontend Masters Boost RSS Feed View TypeScript without Build Tools on frontendmasters.com

TL;DR: There are a bunch of tools these days that allow you to write in TypeScript and… just not think about it much more than that. You needn’t deal with converting that code into JavaScript yourself.


Here’s what has me thinking about all that.

We’ve got a monorepo at work.

We’ve been moving to TypeScript for years, with mostly positive results. I’m fairly convinced that the code output from writing in TypeScript is better and the experience of writing and editing existing TypeScript code is better DX.

It’s not without challenges though. I hate wasting time futzing with types when I just know it really isn’t improving the quality of my code I’m just fighting with a machine. This concern is multiplied when you see your team doing the same thing.

Another challenge is the part where you actually have to produce JavaScript. This is not a difficult job in and of itself. There are loads of tools that do this from the canonical tsc to tools that do no type checking but can very speedily compile TS to JS (like esbuild). But sometimes, you still have to do it.

One example from our monorepo is that we have some components that we’d like to write in .tsx, but they can be consumed by a number of different site building tools (e.g. a Next.js site, an Astro site, an classic Just Load React On The Page site, etc). The most sane way of handling this is processing the TS into JS ahead of time. That way whatever site that wants to import them can do it as native, normal JavaScript ESM stuff.

monorepo
website-1
website-2
packages
components
dist
MyVeryImportantComponent
index.js
src
MyVeryImportantComponent
index.tsx

Now I need to make a build process to do this. I’ll probably write a little script. npm run process-packages or whatever, fine. I’ll probably use tsc for this on purpose, knowing that it isn’t the fastest, but it’s the one that is capable of actually throwing errors when there are TypeScript problems. This is useful because I can call my script in a pre-commit hook in Git, for example, to prevent myself and my team from committing bad TypeScript. I can call the script in CI as well which is additional protection.

So now I have tsc building from src to dist, great. But TypeScript explicitly will never build an “other files” copy machine. Well that’s annoying. What about my other stuff?

packages
components
src
MyVeryImportantComponent
index.tsx
queries.graphql
styles.module.scss

Now I have to wire up some new machine to copy anything that isn’t TypeScript over from src to dist. Blech. Fine, I’ll do it.

But this is all complicated by the fact that this script we’re building needs to be able to run two ways:

  1. As a builder, where you call it and it does the job
  2. As a watcher, where it runs the build when any pertinent file changes

It’s unacceptable DX to expect a developer to run a build command after every file change manually. So we have to build our own little watcher too. I guess it’s Chokidar time? I hate piling on dependencies, but that’s the only watcher that’s ever felt truly reliable to me.

I don’t mean to paint this picture too negatively. This is all doable. This is the job. There are tools to help with this that get better over time. But wow, it’s a lot when you consider it was just TypeScript, this invisible layer of special code helping syntax, that pushed us this far into toolsville.

I’d rather focus on the positive stuff I’m seeing here. As the years tick by, and TypeScripts popularity remains high, the surrounding tools that deal in JavaScript are more and more fine with “just leave it as TypeScript.” I find that interesting!

This “native” support of TypeScript is a product choice. We know some of our customers write and prefer TypeScript so we’ll make it easier for them. But there is no Official™ way to do this. The product needs to decide how they are going to handle it. Are they going to check types for you and alert you (somehow? somewhere?) to type problems? Or are they leaving type problems to you, and if the code compiles to JavaScript, so it shall be. What version of TypeScript is it going to support? Is configuration necessary?

So what are these products?

Tools & Products That Let You Write TypeScript “Natively”

Frameworks

Runtimes

Bundlers

Meta

Drumroll?

I started writing this post a few weeks ago, and now I’ve just seen: Node.js Now Supports TypeScript By Default.

Node 23 will soon be able to run TypeScript files without any extra configuration.

You can run node index.ts with no further flags

Node will strip out the types using a version of swc, then run the resulting code.

Well there ya have it. Feels like we were on to something there eh?

I feel like this pushed it more into Official™ territory and now this will be less of a product-level choice and more of a “leverage what the technology already does” choice. For instance, products don’t have do anything special or build additional technology to support TypeScript, they’ll just do what Node does. And they won’t have to fret over “well should we do type checking?” because they can just follow in the steps of what the tool already does (just strip them).

Scroll to top