Accidentally running TypeScript code directly with `node` without `ts-node`, why does it work?

I have set up a very simple node.js project with TypeScript. My package.json, from which you can see what packages I have installed (there is no ts-node), looks like this:

  "name": "mydemo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "lint": "eslint . --fix",
    "test": "echo \"Error: no test specified\" && exit 1",
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@types/node-fetch": "^2.6.1",
    "@typescript-eslint/eslint-plugin": "^5.23.0",
    "@typescript-eslint/parser": "^5.23.0",
    "eslint": "^8.15.0",
    "node-fetch": "^3.2.4",
    "ts-node": "^10.7.0",
    "typescript": "^4.6.4"

Project structure:

enter image description here

The src/main.ts:

const sayHi = () => {


My tsconfig.json:

    "compilerOptions": {
        "target": "es2016",
        "module": "commonjs",
        "outDir": "dist",
        "esModuleInterop": true, 
        "forceConsistentCasingInFileNames": true,
        "strict": true,
        "skipLibCheck": true 

With the above setup, I can run node src/main.ts on terminal. Whenever I update code in main.ts I directly run node src/main.ts also shows the result with latest code.

I could have installed ts-node, I tried and it works as well. But I wonder why without ts-node my setup works just fine. I mean I can already run TypeScript code by node command without the need to compile to and run JS.

Could someone please explain to me? Seems ts-node is not needed at all.

>Solution :

TypeScript syntax is a superset of JavaScript. Your code does not use any TypeScript specific syntax (like type declarations or type annotations), so it’s also a valid JS file, which plain node can execute. If you add some type annotations, you’ll get an error with node:

const sayHi = (n: number) => {


Leave a Reply