'How to watch and reload ts-node when TypeScript files change

I'm trying to run a dev server with TypeScript and an Angular application without transpiling ts files every time.

What I found is that I can run .ts files with ts-node but I want also to watch .ts files and reload my app/server. An example of this is the command gulp watch.

Thank you in advance!!



Solution 1:[1]

You can now simply npm install --save-dev ts-node nodemon and then run nodemon with a .ts file and it will Just Work:

nodemon app.ts

Previous versions:

I was struggling with the same thing for my development environment until I noticed that nodemon's API allows us to change its default behaviour in order to execute a custom command.

For example, for the most recent version of nodemon:

nodemon --watch "src/**" --ext "ts,json" --ignore "src/**/*.spec.ts" --exec "ts-node src/index.ts"

Or create a nodemon.json file with the following content:

{
  "watch": ["src"],
  "ext": "ts,json",
  "ignore": ["src/**/*.spec.ts"],
  "exec": "ts-node ./src/index.ts"      // or "npx ts-node src/index.ts"
}

and then run nodemon with no arguments.

By virtue of doing this, you'll be able to live-reload a ts-node process without having to worry about the underlying implementation.

Cheers!


And with even older versions of nodemon:

nodemon --watch 'src/**/*.ts' --ignore 'src/**/*.spec.ts' --exec 'ts-node' src/index.ts

Or even better: externalize nodemon's config to a nodemon.json file with the following content, and then just run nodemon, as Sandokan suggested:

{
  "watch": ["src/**/*.ts"],
  "ignore": ["src/**/*.spec.ts"],
  "exec": "ts-node ./index.ts"
}

Solution 2:[2]

I've dumped nodemon and ts-node in favor of a much better alternative, ts-node-dev https://github.com/whitecolor/ts-node-dev

Just run ts-node-dev src/index.ts

Solution 3:[3]

Here's an alternative to the HeberLZ's answer, using npm scripts.

My package.json:

  "scripts": {
    "watch": "nodemon -e ts -w ./src -x npm run watch:serve",
    "watch:serve": "ts-node --inspect src/index.ts"
  },
  • -e flag sets the extenstions to look for,
  • -w sets the watched directory,
  • -x executes the script.

--inspect in the watch:serve script is actually a node.js flag, it just enables debugging protocol.

Solution 4:[4]

This works for me:

nodemon src/index.ts

Apparently thanks to since this pull request: https://github.com/remy/nodemon/pull/1552

Solution 5:[5]

Specifically for this issue I've created the tsc-watch library. you can find it on npm.

Obvious use case would be:

tsc-watch server.ts --outDir ./dist --onSuccess "node ./dist/server.js"

Solution 6:[6]

you could use ts-node-dev

It restarts target node process when any of required files changes (as standard node-dev) but shares Typescript compilation process between restarts.

Install

yarn add ts-node-dev --dev

and your package.json could be like this

"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1",
  "tsc": "tsc",
  "dev": "ts-node-dev --respawn --transpileOnly ./src/index.ts",
  "prod": "tsc && node ./build/index.js"
}

Solution 7:[7]

Summary of options from other answers

Alternative 1: nodemon/node-dev + ts-node + swc

? TL;DR: fastest

An alternative option that combines the reliability of nodemon/node-dev with the speed of ts-node-dev is to use ts-node with swc, a TypeScript-compatible transpiler implemented in Rust which is an "order of magnitude faster" than the TypeScript transpiler.

Note that swc does not do type checking, which should be acceptable since most editors have type checking built-in, and type checking should still be part of your build process.

  1. Install nodemon or node-dev (whichever you prefer)

    • nodemon

      npm install --save-dev nodemon 
      
    • node-dev

      npm install --save-dev node-dev 
      
  2. Set up ts-node with swc integration

    https://github.com/TypeStrong/ts-node#swc-1

    1. Install necessary packages

      npm install --save-dev ts-node @swc/core @swc/helpers regenerator-runtime
      
    2. Add this to tsconfig.json

        "ts-node": {
          "swc": true
        }
      
  3. Run nodemon or node-dev, e.g

    nodemon --watch src src/index.ts
    

    or:

    node-dev src/index.ts
    

Alternative 2: nodemon/node-dev + ts-node transpileOnly

? TL;DR: fast, reliable

Here's an alternative that's slower than the previous option because it uses the standard TypeScript transpiler, but in my testing it's still faster than nodemon/node-dev + ts-node.

Basically it's the same as the previous option but without swc. It's faster than out-of-the-box ts-node by disabling type checking (see notes above regarding why this should be acceptable).

  1. Install nodemon/node-dev as above

  2. Install ts-node

    npm install --save-dev ts-node
    
  3. Modify your tsconfig.json to enable transpileOnly for ts-node

      "ts-node": {
        "transpileOnly": true
      }
    
  4. Call nodemon/node-dev as above

Alternative 3: nodemon + tsc --incremental

? TL;DR: fast, reliable, fewest dependencies, more finicky

This is nearly the same speed as the previous alternative. Out of the three options, this requires the least dependencies (just nodemon, plus the TypeScript compiler, which you already have installed if you're using TypeScript).

(It's possible that this may work with node-dev as well, but I didn't see an exec option for node-dev)

In terms of downsides, it can be a bit more finicky; in my testing, I'm using dotenv to pick up my .env file for local development. But depending how your tsc build is configured in tsconfig.json, you may have to do some acrobatics to get it working.

But it's good to have options, so here it is:

  1. Install nodemon as above

  2. Configure tsconfig.json to transpile your TypeScript to JavaScript

    In particular, noEmit should not be set to true

  3. Configure nodemon to run the TypeScript compiler to do an incremental transpilation any time a TypeScript file is changed, e.g.

    "dev": "nodemon -e ts --watch src .env --exec \"tsc --incremental && node src/index.js\"",
    

    You can even remove --incremental to further simplify it, but it will end up being much slower, comparable to nodemon/node-dev + ts-node.

Solution 8:[8]

Add "watch": "nodemon --exec ts-node -- ./src/index.ts" to scripts section of your package.json.

Solution 9:[9]

i did with

"start": "nodemon --watch 'src/**/*.ts' --ignore 'src/**/*.spec.ts' --exec ts-node src/index.ts"

and yarn start.. ts-node not like 'ts-node'

Solution 10:[10]

I would prefer to not use ts-node and always run from dist folder.

To do that, just setup your package.json with default config:

....
"main": "dist/server.js",
  "scripts": {
    "build": "tsc",
    "prestart": "npm run build",
    "start": "node .",
    "dev": "nodemon"
  },
....

and then add nodemon.json config file:

{
  "watch": ["src"],
  "ext": "ts",
  "ignore": ["src/**/*.spec.ts"],
  "exec": "npm restart"
}

Here, i use "exec": "npm restart"
so all ts file will re-compile to js file and then restart the server.

To run while in dev environment,

npm run dev

Using this setup I will always run from the distributed files and no need for ts-node.

Solution 11:[11]

add this to your package.json file

scripts {
"dev": "nodemon --watch '**/*.ts' --exec 'ts-node' index.ts"
}

and to make this work you also need to install ts-node as dev-dependency

yarn add ts-node -D

run yarn dev to start the dev server

Solution 12:[12]

Another way could be to compile the code first in watch mode with tsc -w and then use nodemon over javascript. This method is similar in speed to ts-node-dev and has the advantage of being more production-like.

 "scripts": {
    "watch": "tsc -w",
    "dev": "nodemon dist/index.js"
  },

Solution 13:[13]

STEP 1: You can simple install nodemon and ts-node (skip if you already done)

npm install --save-dev nodemon ts-node

STEP 2: You can configure the start script in package.json

"start": "nodemon ./src/app.ts"

As now nodemon automatically identify the typescript from the project now and use ts-node command by itself. Use npm start and it will automatically compile/watch and reload.

If you get any errors like typescript module not found in the project. simple use this command in the project folder.

npm link typescript

Solution 14:[14]

Just update these 3 packages

nodemon, ts-node, typescript
yarn global add nodemon ts-node typescript

or

npm install -g nodemon ts-node typescript

and now you can run this, problem solved

nodemon <filename>.ts

Solution 15:[15]

Clear logs of the console after changing

Javascript:

"start": "nodemon -x \"cls && node\" index.js",

Typescript:

"start": "nodemon -x \"cls && ts-node\" index.ts",

Solution 16:[16]

If you are having issues when using "type": "module" in package.json (described in https://github.com/TypeStrong/ts-node/issues/1007) use the following config:

{
  "watch": ["src"],
  "ext": "ts,json",
  "ignore": ["src/**/*.spec.ts"],
  "exec": "node --loader ts-node/esm --experimental-specifier-resolution ./src/index.ts"
}

or in the command line

nodemon --watch "src/**" --ext "ts,json" --ignore "src/**/*.spec.ts" --exec "node --loader ts-node/esm --experimental-specifier-resolution src/index.ts"

Solution 17:[17]

With nodemon and ts-node:

nodemon --watch source --ext ts,json --exec "node --loader ts-node/esm ./source/index.ts"