18 July 2023
How to speed up a TypeScript project
TypeScript became a standard for backend (Node.js) and frontend (Angular/React) development. The types it brings allow us to develop apps with the confidence that we won’t make any silly mistakes. It doesn’t relieve us from the responsibility of using best coding practices, but it does make developers’ lives a bit easier. Yet there is one downside of TS. It’s compile time. So, let’s talk about how to speed up your TypeScript project.
Optimizing TypeScript projects is something we pay a lot of attention to. Not only is it one of our key technologies, the State of Frontend 2022 shows that this is how the majority of frontend developers feel these days – 84,1% of all respondents admitted to using TypeScript over the last year!
So, how can you improve the speed of your TypeScript project?
What you’ll learn
There are various approaches, but in this one I’m going to focus on shortening the transpilation time to JavaScript. Other than that, you’re going to find out about:
- using the Superfast JavaScript/TypeScript Compiler (SWC),
- various ways to use the TypeScript compiler, including the – –noEmit flag,
- our own Express Boilerplate and the way we use at The Software House it to optimize projects.
Let’s start with some basic facts about compiling TypeScript.
Compiling TypeScript – the woes of tsc use
The more code you have, the longer it takes to compile. I think we can all agree on that. In some cases, that’s also the reason why we split the application into smaller pieces (services), so we don’t need to compile the entire project and file system, including json file and all the rest.
Let’s take our Express Boilerplate (the starter we’re using to build apps for our clients). To speed up the development process, regardless of how many files the project references, we’ve built a starter pack that reflects our way-to-go stack.
This includes:
- production-ready containerization,
- TypeScript support,
- Plop for code generation,
- built-in support for Redis and PostgreSQL with TypeORM,
- best practices like Command pattern or Dependency Injection with Awilix
- REST/graphQL API support,
and more!
In its raw form, running the `npm run watch` command (which starts the TypeScript Compiler – tsc – in a watch mode) takes 28 seconds to have an environment ready to work with.
It doesn’t sound like a lot, but with more code to come, this number will slowly increase. So what happens during TypeScript compilation?
TypeScript compilation process
In short, there are two major components:
- types checking,
- transpilation to JavaScript
At this point we cannot do much with type checking, however, there is a way to speed up the compilation speed.
TypeScript itself can’t change TS source code into JS files. There is no such functionality. However, there is one that allows us to check types only – –noEmit flag.
So what if we used something faster for a transpilation part and use TSC only for TS types checking?
Introducing… SWC!
Improving the efficiency of TypeScript-based projects is what we do.
Check out the case study of a major events platform to see how we enhanced the scalability and usability of the AWS- and TypeScript-based application.
What is SWC?
SWC stands for Superfast JavaScript/TypeScript Compiler. It is a tool, created in Rust, that has one job – to transpile the code from TS/ES to a specific target. It won’t check the types (at least not yet), but because of that, it is much faster than TSC.
Our Boilerplate compiles in 7 seconds. That’s 4 times faster than using the built-in TypeScript tools. So how does it work?
SWC can be installed as standard devDependency with:
npm i -D @swc/core @swc/cli
And that’s all! At least for some basic features. 🙂
You can try it by running:
swc <some-directory> --out-dir build
… and in a second you should get the code transpiled. If you need to have a watch mode, then just add the -w flag at the end.
Of course, it is a little bit more complicated for more complex projects. By default SWC has most of the features turned off and for many TypeScript applications, it will be necessary to add additional configuration
This could be done with a special single file: .swcrc file. Check out the following code:
Sadly there is no tool that creates swc configuration from tsconfig yet. Therefore, you should remember to keep both files in sync.
There are a few useful keys in the SWC config.
The first one is jsc. This key contains everything related to the parser type we’re going to use – for example typescript or ECMAScript, but also some information about the target js version we want our code to be converted to.
The second one is a module. This one is especially useful for Node.js apps, because of the CommonJS modules requirement.
For most of our apps, we also had to turn on the decorators support, otherwise you’ll get a nasty error message.
Obviously, those are only a few of the many possible configuration options. Feel free to check the remaining ones on the SWC configuration website.
🏃♂️ Sports activities and serverless? Learn how we built an architecture for data-driven systems!
What about types?
One question remains unanswered. Do we drop types checking? In fact, SWC doesn’t care about the code validity nor it cares about types. So in reality we’re losing the biggest reason to use TypeScript for. What the hell?! Don’t worry we are not doing that. 😊
At the beginning of this article, I mentioned that TS can work in two ways. It either generates the code and checks types or only checks types. Let’s use the second approach then!
The command we need is simple:
tsc -w --pretty --skipLibCheck --noEmit
Yet we still need to run both in parallel – SWC and TSC. We can either use a library for that (to have cross-operating system functionality) or we can just use and run both simultaneously.
swc src --out-dir build/src -w --sync & tsc -w --pretty --skipLibCheck --noEmit
What is the benefit of that approach?
The app is ready to develop in 7s, and at the same time, we’re going to get all of the information about possible errors in our code.
The larger our app gets, the bigger the difference between SWC and TSC is going to be, so having the possibility to develop earlier is a huge advantage.
Of course, there are other topics related to the –noEmit flag, which I’ll not get into this time. Please, check out and learn more about: declaration files, the package dependency graph, or the tsbuildinfo file.
💡 Want to read more about TypeScript? Check out some of our newest articles on that!
- Why use TypeScript? Could it be the best way to write frontend in 2023?
- Practical code examples of why Typescript is the best choice for frontend
- New TypeScript features bring even more efficiency & protection to your code. Check out TypeScript version 4.1-5.0 overview
- It's not JavaScript's ugly cousin. See how Typescript improves Developer Experience
So… how to speed up your TypeScript project?
So where is the catch? – you may ask. Well, there are a couple of things to remember:
- The TypeScript code generated with SWC is a little bit different from the one generated by TSC. In some cases, this leads us to some issues with our tsc-working application. For example, depending on a configuration, decorated classes are returned as classes or objects (yet in tsc it is always going to be a class).
- It doesn’t sound bad, but if any of your functions requires the specific type (for example class), it will break. We had this problem with the Awilix helper asClass.The other problem is the support of new features.
- SWC is evolving pretty quickly, yet it still doesn’t support all of the features that TSC/Babel does. The most up-to-date list of features is available on the SWC website. But it is also worth checking the GitHub issues pages.
So would I recommend using SWC?
There is a bright side here. It is very easy to change TypeScript code and switch back and forth between SWC and TSC, so I’d say we all should give it a try!
At The Software House we’re going to play with this a little bit more to see how stable it is in larger projects. However, at this point I’m very happy with the results!
Do you want to build faster with TypeScript? This is just one of many questions you need to answer for your next project.
Contact The Software House and tackle them all. Initial consultations are free of charge!