Is babel still relevant for TypeScript projects ?
Tags: typescript, javascript, babel, webpack
Published: 2021-06-02 18:03:25

---
title: Is babel still relevant for TypeScript projects ?
published: true
description: Since TypeScript can transpile your JS code, are there still reasons to use babel ?
tags: #typescript #javascript #babel #webpack
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/is5e0btpwjecsfw7mq33.png
---

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](https://www.reddit.com/r/typescript/comments/d80xz4/is_babel_redundant_if_typescript_is_involved/), [2](https://www.reddit.com/r/typescript/comments/6pdcy2/transpiling_typescript_right_to_es5_or_combined/))
- 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](https://www.typescriptlang.org/)), or that "You might use [babel] for speed or consistency with your existing build tooling"([2](https://www.typescriptlang.org/download)).

**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] (https://twitter.com/mbeaudru)

## 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](https://www.typescriptlang.org/tsconfig#target) like ES5 or specific nodeJS versions.

For instance, [I created the most minimalistic TypeScript project](https://gist.github.com/mbeaudru/24055dd6042e90d95642c5fc48856454) without configuring any options, and this is what I got:

**Input (index.ts):**

```ts
const helloWorld = () => {
  console.log("hello world");
};
```

**Output (index.js):**

```js
"use strict";

var helloWorld = function () {
  console.log("hello world");
};
```

[TypeScript has generated a default tsconfig.json](https://gist.github.com/mbeaudru/881046f1c03467a2bf2e85007d8bb178) 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](https://babeljs.io/docs/en/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:

- [Smart Bundling: How to serve legacy code only to legacy browsers](https://www.smashingmagazine.com/2018/10/smart-bundling-legacy-code-browsers/)
- [Differential Serving — Serve legacy code to old browsers and ES6 code to modern browsers](https://medium.com/@suncommander/differential-serving-serve-legacy-code-to-old-browsers-and-es6-code-to-modern-browsers-bbd4152cf979)

### 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:

```jsx
if (__DEV__) {
  console.log('foo');
}
```

- 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](https://styled-components.com/docs/tooling#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](https://github.com/Igorbek/typescript-plugin-styled-components), but:

- it's not as feature-rich as the official babel plugin ([ref](https://github.com/Igorbek/typescript-plugin-styled-components#minify))
- it requires to use webpack in combination of the ts compiler, since the tsc doesn't allow plugins to apply code transformers ([ref](https://github.com/Microsoft/TypeScript/issues/16607))

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](https://github.com/jgierer12/awesome-babel-macros).

### 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](https://swc-project.github.io/docs/installation/) or [Sucrase](https://github.com/alangpierce/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](https://nextjs.org/) for a web app or [TSDX](https://tsdx.io/) to build a TS library. TS doc suggests the same thing, the [Bootstrap page](https://www.typescriptlang.org/docs/bootstrap) 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](https://babeljs.io/) or [SWC](https://swc-project.github.io/docs/installation/) 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 👍