DocsBlogAbout

Lightning Fast TypeScript

You are not alone, running TypeScript directly can be painfully slow... is it? Not anymore.

banner image

I’ve been dreaming about learning Go because my TypeScript apps have this slightly annoying start delay making them feel so not very snappy. For a long while I got used to continuously build my code with tsc --watch. The constant pre-compile step is less disturbing than the time ts-node took to load.

Another pain point was how to configure my compiler. All my code was under ./src but kept my scripts under ./task to prevent shipping devops code by accident. Since I did not have pre-compiled code for this I did force myself to never compile those and just accept the start up delay.

Alternative Node runtimes

It was not until I started using Deno that I realized how fast TypeScript code can be. It had some minor pains, the most glaring one is requiring relative import paths with the .ts extension while the Node forces imports with .js if you are into esm.

Then came Bun and that was the one to finally kill most of my interest for learning Go. It behaves more like npm than Deno, and while it is not so production ready I do not mind so much running my scripts with it. For the time being I even show a warning to users of tk if Bun is not installed before falling back to Node. The last thing I want is people not using tk because it is slow to start.

There is no lack of runtimes, lately I keep hearing more about WinterCG which seems to lead the path for a better compatibility between them. However it is Deno to whom we must thank the push for TypeScript, they are the ones who introduced the JSR Registry an alternative to the npm registry but with TypeScript and ES modules by default.

On testing

In the area of testing Vitest has also been quite an eye opener. Sometimes I get the impression my .ts files in vitest load faster than my .js files in Mocha or Jest. The one caveat is that it treats CommonJS is a second class citizen, even it is planning to drop support for the next release. That was the project that pushed me to finally embrace esm mode in Node and the reason you will see TaskFolders packages ship esm only.

Don’t be afraid, but don’t go crazy either

Node and the Npm are huge and battle proof. It is not realistic expecting a full move into alternative registries or engines. Remember that Node.js is the engine of choice when uploading code to AWS Lambda or Azure Functions.

Local scripting is a whole different story, you will not break things playing with alternative engines. I removed some git pre-commit hooks because they made each commit so slow. Not anymore, the pleasure of lightning fast TS scripts far encouraged me to keep improving my internal tooling. Now a TS task runs as fast a Bash script. The former might be more verbose, but you get far more reusable code, it is less cumbersome than using GoLang and more type safe than Python.