Introduction
ts-node-dev is a popular development tool that automatically restarts a Node.js TypeScript application when source files change. When file watching stops working, developers must manually restart the server after every code change, significantly slowing down the development cycle.
This issue is common after upgrading ts-node-dev, changing the project structure, or running on systems with file watcher limits (especially Linux and Docker).
Symptoms
- ts-node-dev starts but does not restart when .ts files are modified
- Console shows no change detection after saving files
- File changes are only picked up after manually killing and restarting the process
Common Causes
- tsconfig.json outDir is included in the watch path, causing infinite loops
- File system watcher limit (inotify) is exhausted on Linux
- ts-node-dev is watching the wrong directory or file extensions
Step-by-Step Fix
- 1.Configure ts-node-dev watch paths correctly: Specify which directories to watch.
- 2.```bash
- 3.# Run with explicit watch flags:
- 4.npx ts-node-dev --respawn --transpile-only --watch src src/index.ts
# Or in package.json: { "scripts": { "dev": "ts-node-dev --respawn --transpile-only --watch src src/index.ts" } } ```
- 1.Fix tsconfig.json to exclude build output from watch: Prevent watching compiled files.
- 2.```json
- 3.{
- 4."compilerOptions": {
- 5."target": "ES2020",
- 6."module": "commonjs",
- 7."outDir": "./dist",
- 8."rootDir": "./src",
- 9."sourceMap": true
- 10.},
- 11."include": ["src/**/*"],
- 12."exclude": ["node_modules", "dist"]
- 13.}
- 14.
` - 15.Increase Linux inotify watcher limit: Allow watching more files.
- 16.```bash
- 17.# Check current limit:
- 18.cat /proc/sys/fs/inotify/max_user_watches
- 19.# Default is often 8192, which is too small for large projects
# Increase the limit: echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf sudo sysctl -p
# Verify: cat /proc/sys/fs/inotify/max_user_watches # Should show: 524288 ```
- 1.Use alternative: nodemon with ts-node: If ts-node-dev still doesn't work.
- 2.```bash
- 3.npm install --save-dev nodemon
# nodemon.json: { "watch": ["src"], "ext": "ts", "ignore": ["src/**/*.spec.ts"], "exec": "ts-node --transpile-only ./src/index.ts" }
# In package.json: { "scripts": { "dev": "nodemon" } } ```
Prevention
- Exclude dist/ and node_modules/ from watch paths
- Set --respawn flag to keep the process running after crashes
- Use --transpile-only for faster reloads (skip type checking on every change)
- Run a separate type-checking process (tsc --noEmit --watch) alongside the dev server