Debugging TypeScript projects with VSCode in 2023

Debugging TypeScript projects with VSCode in 2023

A simple config for your Node.js and TypeScript projects to get debugging and auto-restarts working together in just a few minutes.

Featured on Hashnode

I finally decided to invest some time in properly setting up a debugger for my Node + TS projects. console.log is cool and all, but it just wasn't cutting it anymore.

So, I've been reading documentation (plus so many GitHub issues), and trying different solutions, and I ended up with a config that I'm actually happy with!

Keep reading to learn how to:

  1. Create a project with Node.js and TypeScript.

  2. Install a package (ts-node-dev) and configure it so it can run your project and auto-restart on save.

  3. Configure the debugger in VSCode so it uses ts-node-dev to both enable the debugging of .ts files and provide auto-restarts.

  4. Finally, stop relying on console.log('here!') to debug your code :D

Initialize the project

Create a directory for your project and initialize it:

mkdir ts-starter
cd ts-starter
npm init -y

Install TypeScript

Install TypeScript and the type definitions for node:

npm install typescript @types/node --save-dev

Setup your tsconfig

To create the tsconfig.json file, run the following command:

npx tsc --init

The default tsconfig.json generated should look something like this:

{
    "compilerOptions": {
        "target": "ES2016",
        "module": "commonjs",
        "esModuleInterop": true,
        "forceConsistentCasingInFileNames": true,
        "strict": true,
        "skipLibCheck": true 
    }
}

Install ts-node-dev

We’re going to hook up ts-node-dev with the VSCode debugger to get both the debugger and auto-restarts working!

Start by installing the package:

npm install ts-node-dev --save-dev

To quickly try it out, we can create a new script in the package.json:

"scripts": {
    "dev": "ts-node-dev --respawn src/index.ts"
},

Now let’s write some code to run!

Create the src directory and add the following code:

// index.ts

interface Game {
  name: string;
  genre: string;
  platform: string;
}

const game: Game = {
  name: "Super Mario",
  genre: "Platformer",
  platform: "Nintendo",
};

console.log(game);

We’re adding some types so we can make sure the compiler is working properly.

Finally, run the dev script from your terminal:

npm run dev

You should see something like this:

And finally, change the values in your game constant and save the file, to see the automatic restarts in action!

Nice, we can see how the app auto-restarts after we make changes!

Set up the VSCode Debugger

First, let’s generate a launch.json file. To do that:

  1. Open the command palette (Ctrl + Shift + P or Cmd + Shift + P on Mac) and select “Debug: Add Configuration”

  2. On the next step, select Node.js for the Debugger

You should get an auto-generated launch.json file, like this one:

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "node",
            "request": "launch",
            "name": "Launch Program",
            "skipFiles": [
                "<node_internals>/**"
            ],
            "program": "${workspaceFolder}\\\\src\\\\index.ts",
            "outFiles": [
                "${workspaceFolder}/**/*.js"
            ]
        }
    ]
}

Replace it with the following configuration:

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "node",
            "request": "launch",
            "name": "Launch + auto-restart",
            "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/ts-node-dev",
            "args": [
                "--respawn",
                "${workspaceRoot}/src/index.ts" 
            ]
        }
    ]
}

The main properties to notice here are:

  • runtimeExecutable: By default, this would be node, but we are replacing it with ts-node-dev

  • args: We’re adding the --respawn flag, which tells ts-node-dev to restart the process when files change, and then we add the path to our startup file.

Essentially, these two properties produce a result similar to the ts-node-dev --respawn src/index.ts script we set up earlier in the package.json.

Now, let’s try it!

Press F5 to start the debugger. You should see the output on VSCode’s integrated terminal:

Try adding a breakpoint, and then make some changes and save:

The app should restart and hit the breakpoint!

That's it!

What I love about this config is how simple it is. All we needed was ts-node-dev, a few tweaks to the debugger config file, and it just works!

Although, to be completely honest, I'll probably still use console.log('here') every now and then, just for old times' sake.


My book: typescriptgamified.com | Find me here: paulasantamaria.com/links