# Debugging TypeScript projects with VSCode in 2023

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:

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

## Install TypeScript

Install TypeScript and the type definitions for node:

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

## Setup your tsconfig

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

```bash
npx tsc --init
```

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

```json
{
    "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:

```bash
npm install ts-node-dev --save-dev
```

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

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

```typescript
// 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:

```bash
npm run dev
```

You should see something like this:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1681610527820/e3bea4f7-11a9-4cf6-8026-0a84adb89f3a.png align="center")

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

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1681610572334/bc2163d0-fe2b-4ba6-88c5-bde31300d645.gif align="center")

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:

```json
{
    "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:

```json
{
    "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:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1681610612870/524ebbb0-6397-472a-bbcc-8c9cee69f112.png align="center")

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

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1681610661284/d92d0133-4214-48a8-bc59-b830e623f084.png align="center")

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.

---

[![](https://www.typescriptgamified.com/_app/immutable/assets/banner-01-16795b9b.webp align="left")](https://www.typescriptgamified.com)

My book: [typescriptgamified.com](https://typescriptgamified.com) | Find me here: [paulasantamaria.com/links](https://paulasantamaria.com/links)
