DEV Community

loading...
Cover image for Is babel still relevant for TypeScript projects ?

Is babel still relevant for TypeScript projects ?

Manuel Beaudru
โœ๏ธ Modern JS Cheatsheet author โš›๏ธ JS/TS React developer @deezer - previously @mirakl ๐Ÿ‡ซ๐Ÿ‡ท
ใƒป5 min read

Since TypeScript has the ability to generate a JavaScript bundle using the TypeScript compiler, are there still reasons to bother using babel and webpack when you want to create a new ts-based project ?

Unsatisfying answers

My 5min google search on the topic didn't give me satisfying answers:

  • on reddit, there are many voices arguing that the tsc is enough (1, 2)
  • but most project scaffolding tools (create-react-app, nextjs, tsdx to name a few) still rely on babel + webpack or rollup.
  • Besides, TypeScript folks themselves state that "TypeScript code is transformed into JavaScript code via the TypeScript compiler or Babel" (1), or that "You might use [babel] for speed or consistency with your existing build tooling"(2).

Why is that ? Should you solely rely on tsc at your company or on your next pet project ?

I've done the work for you, so let's dive in ๐Ÿ™‚

๐Ÿ‘‰ Want to see more ? Follow me on Twitter

TypeScript is a self-sufficient build tool

The TypeScript compiler has the ability to produce a JavaScript bundle. It is capable of generating an "older" JS for specific targets like ES5 or specific nodeJS versions.

For instance, I created the most minimalistic TypeScript project without configuring any options, and this is what I got:

Input (index.ts):

const helloWorld = () => {
  console.log("hello world");
};
Enter fullscreen mode Exit fullscreen mode

Output (index.js):

"use strict";

var helloWorld = function () {
  console.log("hello world");
};
Enter fullscreen mode Exit fullscreen mode

TypeScript has generated a default tsconfig.json that targets ES5, so the arrow function has been transpiled to a regular function and the const has been changed for a var.

As you can see, tsc has done a pretty good job at transpiling the code. Indeed, it is a legit transpiler and it might be enough for you. Besides, we didn't needed to get webpack into the mix and it was very easy to set up.

At this point you might be wondering, what does the TypeScript compiler is missing that Babel isn't ?

Babel comes with many benefits

If you look at the surface, indeed Babel and TypeScript are both capable of transpilation, but babel is capable of covering a much broader range of scenarios and the power to fine-tune what code is generated.

Optimized build for legacy browsers and modern browsers ๐Ÿš€

With Babel + babel-preset-env, you have more control on what your target is. For instance you can target every browser above IE11, or > 0.25% of browsers that are not dead.

Going further, you can even generate two bundles: one for legacy browsers, and one for modern browsers that will be much lighter & easy to process.

You can learn more about this topic on the two following articles, that I particularly enjoyed:

Tree-shaking and Quality of life improvements โ›ฑ๏ธ

Let's dive in into the TSDX case:

TSDX is a zero-config CLI that helps you develop, test, and publish modern TypeScript packages

I find this example very interesting, because this tool is solely focused on generating TypeScript packages, but they still use babel anyway.

In a nutshell, they use babel to:

  • Generate an optimized production bundle, that will remove development specific instructions like this:
if (__DEV__) {
  console.log('foo');
}
Enter fullscreen mode Exit fullscreen mode
  • Prevent you from accidentally import all lodash by rewriting the imports at transpile time + changes lodash to lodash-es to make your library treeshakable to end consumers.

A rich and powerful plugin ecosystem ๐Ÿ“ฆ

For instance, styled-components provides a babel-plugin to add support for server-side rendering, minification of styles, and a nicer debugging experience..

In this particular case, there is an alternative to make it work without babel, but:

  • it's not as feature-rich as the official babel plugin (ref)
  • it requires to use webpack in combination of the ts compiler, since the tsc doesn't allow plugins to apply code transformers (ref)

Besides, this plugin is one of the most popular ones so there is a babel alternative. But you are not guaranteed to have the same escape-hatch for other transformers.

Retro-Compatibility ๐Ÿ“ผ

For instance, create-react-app and NextJS still need to support non-TypeScript powered projects (ex: JavaScript or Flow), it makes sense for those tools not to center their entire system around the TypeScript compiler.

For the same reason, it's also easier in a legacy JavaScript codebase built with babel+webpack to migrate to TypeScript incrementally and with confidence, since it will only consist of adding the @babel/preset-typescript to the mix for .ts and .tsx files.

You won't need to "remove" babel from your pipeline and touch your existing configuration.

Build-time performance โšก

When using babel to transpile your TS into JS, there is no type-checking that is performed on the TypeScript codebase: babel simply "removes" every TS-specific instructions and only keeps the JS, then applies its transformations.

This can arguably be seen as a downside, since TS code with invalid typing will be built without crashing or warning you of issues.

But you can see it as an upside: you can run tsc in a process just for the type-checking phase, and babel in a parallel process to generate the build.

๐Ÿ”ฅ Besides, there are babel alternatives growing up like SWC or Sucrase that are heavily focused on compilation speed and are much faster than the tsc transpiler or babel.

Conclusion

TypeScript compiler is capable of transpiling your code, but it is not as flexible, powerful and complete as Babel.

If you are starting a new project from scratch, you're probably better of using a generator like NextJS for a web app or TSDX to build a TS library. TS doc suggests the same thing, the Bootstrap page is very useful in that regard.

Such tools are making the choice and configuration of the transpiler behind the scenes, and most of them use Babel for all the reasons we saw together.

And if you're a company that wants to have all the controls on the tooling, my advice would be to use TypeScript compiler solely for the type-checking phase and Babel or SWC for the transpilation phase.

Indeed, babel gives you the fine-tuning control you might need, while SWC gives you the speed if you don't need what babel provides.

What do you use in your project/company ? Do you have a use case I didn't cover that you want to highlight ? Don't hesitate to react in the comments and I'll gladly respond ๐Ÿ‘

Discussion (5)

Collapse
alexburner profile image
Alex Burner

One important aspect of babel-preset-env I think you missed: Browser Polyfills. TypeScript can transpile syntax down for older browsers, but it won't add runtime code to support something like String.prototype.replaceAll() in IE11

Collapse
mbeaudru profile image
Manuel Beaudru Author

Indeed, I will update the post this weekend to add this point ๐Ÿ‘

I thought that TypeScript added polyfills, but it doesn't and adding them is not trivial either.

Thanks !

Collapse
jackmellis profile image
Jack

Great article! Babel is totally still useful, there are a lot of things babel can do over tsc, like literally anything. Until typescript has a plugin system where you can easily include extra transpilers and parsers, babel will always be the more flexible option. If anything I feel like since the typescript preset came out, the question should be "do we still need tsc?"

Collapse
mbeaudru profile image
Manuel Beaudru Author

Thank you !

Pretty much my conclusion indeed, I don't see a scenario where using tsc for the transpiling phase is better now?

But it was not obvious at a first glance, as the reddit answers and my own interrogation shows. Maybe that's because as you said, at the beginning of TypeScript, Babel wasn't an easy option since the TS plugin didn't existed

Collapse
beyarz profile image
Beyar

Very interesting!