Aro Andriamaro

Software Developer

Setup a simple Node Typescript Project in 5 minutes - 2024 edition

Desk with computer desktop
Generated with AI

We are in May 2024, I just want to setup a simple Node project. But it’s so freaking hard. I tried every blog post in google’s first page results. None are working, at least as I want it.

Why is it so ducking 🦆 hard to have a Node development setup that is in Typescript and uses ESM !?

So, after a frustrating couple of hours of searching and tweaking, I finally found a way to have a simple setup that just works (for now)

Requirements

So as I said, I want to it to use

That’s literally it.

The solution

Dependencies

First of all, install all the dependencies

Terminal window
pnpm i -D typescript @types/node tsx tsc-alias rimraf

DISCLAIMER: I am NOT an experienced Node developer. I mostly work in frontend development with React. This is just a simple node setup that works for me. I am sure it’s possible to make it even simpler without relying on third party dependencies like tsx and tsc-alias.. But I am just not in the mood of digging further 🥲

tsconfig.json

For the tsconfig file, I use the config from this TotalTypescript blog post.

NOTE : I did try to follow this blog post steps. But I didn’t like to have two dev scripts that run concurrently. At the time, I was playing with some AI stuff and was trying to console.log the stream response from the AI, and it just didn’t get displayed to the console. I suspect this concurrent run of two dev scripts.

{
"compilerOptions": {
"esModuleInterop": true,
"skipLibCheck": true,
"target": "es2022",
"allowJs": true,
"resolveJsonModule": true,
"moduleDetection": "force",
"isolatedModules": true,
"strict": true,
"noUncheckedIndexedAccess": true,
"moduleResolution": "NodeNext",
"module": "NodeNext",
"outDir": "dist",
"sourceMap": true,
"lib": ["es2022"],
/* I add this part because I want absolute imports */
"baseUrl": ".",
"paths": {
"src/*": ["src/*"]
}
}
}

package.json

{
"type": "module",
"scripts": {
"build": "rimraf dist && tsc --project tsconfig.json && tsc-alias -p tsconfig.json",
"dev": "NODE_ENV=development tsx --watch --env-file=.env src/index.ts",
"start": "node --env-file=.env dist/index.js"
},
"engines": {
"node": "20"
}
}

Caveats when importing a file

This is the last thing you want to be aware of. When importing a file, you have to suffix the import paths with .js

import { hello } from "src/utils/hello.js";

Conclusion

And that’s it, holy cow I struggled so much just to find this setup. Some of you that are already familiar with tsx may call me a noob 😅 and you are not totally wrong.

I was used to use nodemon and ts-node before but my previous setup don’t work anymore 🤷🏽‍♂️

I think it is not not normal that it’s so hard to setup a modern Node project but also to find the right information to do that, as there are literally no single way of doing this.

But in the end I am happy that I succeed (for now). Thanks for reading, ciao ciao

You can find the complete repo here