676

I'm having a surprisingly hard time finding an answer to this. With plain Node.JS, you can run any js file with node path/to/file.js, with CoffeeScript it's coffee hello.coffee and ES6 has babel-node hello.js. How do I do the same with Typescript?

My project has a tsconfig.json which is used by Webpack/ts-loader to build a nice little bundle for the browser. I have a need for a build step run from the console before that, though, that would use some of the .ts files used in the project to generate a schema, but I can't seem to be able to run a single Typescript file without compiling the whole project.

Gunchars
  • 9,555
  • 3
  • 28
  • 27

23 Answers23

882

How do I do the same with Typescript

You can leave tsc running in watch mode using tsc -w -p . and it will generate .js files for you in a live fashion, so you can run node foo.js like normal

TS Node

There is ts-node : https://github.com/TypeStrong/ts-node that will compile the code on the fly and run it through node

npx ts-node src/foo.ts
basarat
  • 261,912
  • 58
  • 460
  • 511
  • What's the difference between these two options? – johnnyodonnell Jul 02 '18 at 03:15
  • 102
    tsc writes js to disk. ts-node doesn't need to do that and runs ts on the fly – basarat Jul 02 '18 at 05:17
  • 7
    just reminder ts-node does not console log from imported modules. For Ex: if you are ts-node fil1.ts and file1.ts uses file2.ts internally, then console logs from file2.ts will not be logged. – Shadab Faiz Oct 11 '18 at 11:21
  • 1
    One red herring to be careful of that I ran into and was confusing me. I had a simple TypeScript file named `test.ts` that was never transpiled and had the single line of code: `console.log('hello');` in it. I was running `node test.ts` from the command line and _it worked_ outputting 'hello` which was confusing me. Well if the file is _purely_ valid JavaScript and you run `node myFile.ts` it _still works._ However this isn't a good use case as the minute I added TypeScript code I got an error upon trying to run it which is what I expected. I wish node would alert/error upon running .ts files. – atconway Mar 27 '19 at 03:51
  • 20
    ts-node FTW. `npm install -g ts-node` makes `ts-node your-script.ts` a breeze. – AlwaysLearning Aug 17 '19 at 00:50
  • 1
    one more cool thing with ts-node: you can install it globally together with typescript and then just add this line to your .ts script: ```#!/usr/bin/env ts-node``` and you can run your .ts script just like any OS script (but don't forget about chown +x) – Oleg Gordeev Jan 21 '20 at 23:51
  • 17
    Since the release of [deno](https://deno.land/), you can now execute `deno run path/to/file.ts` and it will run typescript files in a single command without compiling it to a separate JS file. – JMadelaine May 13 '20 at 23:45
  • 10
    Careful with deno as it is *distinct* from node and code that will work in node might not work in deno (due to built-in and npm nodejs packages) – basarat May 14 '20 at 00:33
  • 1
    @JMadelaine Deno does compile to a JavaScript module file and writes it to a generated cache directory each time you run the source file. See `DENO_DIR` at https://deno.land/manual@v1.10.1/getting_started/setup_your_environment#environmental-variables – jsejcksn May 14 '21 at 10:15
  • 1
    Uncaught SyntaxError: Unexpected token 'export' – David 天宇 Wong Nov 22 '21 at 22:33
  • 1
    As of May 2022 ts-node does support es modules `npx ts-node --esm file.ts` https://www.npmjs.com/package/ts-node#commonjs-vs-native-ecmascript-modules – bcbrian May 04 '22 at 18:15
  • 1
    In my case I had to add a `--skipProject` to just ignore everything in `tsconfig.json` and run the file without fancy settings. – Dave Oct 23 '22 at 03:12
  • 1
    Got to use the `--esm` flag these days: `npx ts-node --esm src/foo.ts` – igneosaur Mar 17 '23 at 18:35
196

Run the below commands and install the required packages globally:

npm install -g ts-node typescript '@types/node'

Now run the following command to execute a typescript file:

ts-node typescript-file.ts
Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
ziishaned
  • 4,944
  • 3
  • 25
  • 32
  • 5
    this is the best way to do it IMHO, as `ts-node` also provides TypeScript REPL. – tromgy Jan 26 '20 at 19:18
  • 9
    You can also rely on `npx ts-node yourscript.ts` in case you don't want to use global version. – rafaelpivato Feb 22 '20 at 21:41
  • 24
    [`ts-node` doesn't support ES Modules](https://github.com/TypeStrong/ts-node/issues/935#issuecomment-579718641). – Dan Dascalescu Mar 05 '20 at 09:57
  • 2
    The query for the download no longer valid , try ```npm install typescript --save-dev --global && npm i ts-node -g``` instead – 钟智强 Nov 05 '21 at 20:37
  • About `'@types/node'` I recommend taking a look at these links: https://www.npmjs.com/package/@types/node , https://www.alura.com.br/artigos/typescript-favoreca-o-uso-de-type-definitions [], https://blog.angular-university.io/typescript-2-type-system-how-do-type-definitions-work-in-npm-when-to-use-types-and-why-what-are-compiler-opt-in-types/ . – Eduardo Lucio Apr 29 '22 at 20:49
  • ts-node now [supports ES Modules](https://typestrong.org/ts-node/docs/imports/), though this support remains experimental because it depends on Node features that are still experimental – RichVel Nov 11 '22 at 14:52
112

We have following steps:

  1. First you need to install typescript

    npm install -g typescript
    
  2. Create one file helloworld.ts

    function hello(person){
       return "Hello, " + person;
    }
    let user = "Aamod Tiwari";
    const result = hello(user);
    console.log("Result", result)
    
  3. Open command prompt and type the following command

    tsc helloworld.ts
    
  4. Again run the command

    node helloworld.js
    
  5. Result will display on console

KyleMit
  • 30,350
  • 66
  • 462
  • 664
Aamod Tiwari
  • 1,310
  • 1
  • 9
  • 7
49

To add to @Aamod answer above, If you want to use one command line to compile and run your code, you can use the following:

Windows:

tsc main.ts | node main.js

Linux / macOS:

tsc main.ts && node main.js
GabLeRoux
  • 16,715
  • 16
  • 63
  • 81
tony2tones
  • 1,422
  • 1
  • 18
  • 19
45

I created @digitak/esrun, a thin wrapper around esbuild and that executes a TypeScript file almost instantly. esrun was made because I was disappointed with ts-node: too slow, and just didn't work most of the time.

Advantages of esrun over ts-node include:

  • very fast (uses esbuild),
  • can import ESM as well as CJS (just use the libraries of your choice and esrun will work out of the box),
  • there is an included watch mode, run your script with the --watch option and any change to your entry file or any of its dependencies will re-trigger the result
  • you can use esrun in inspect mode to use the DevTools console instead of your terminal console.

After installing, just run:

npx @digitak/esrun file.ts
mikemaccana
  • 110,530
  • 99
  • 389
  • 494
Gin Quin
  • 966
  • 7
  • 15
  • 6
    Omg, exactly what I was looking for, for many many hours ! Couldn't make `ts-node` to work. Simply ran "esrun my-file.ts", and worked out of the box ! – Random Feb 15 '21 at 13:24
  • 6
    Maybe a little disclaimer that you're the author of the library? – Robin Métral Mar 24 '21 at 19:57
  • 10
    @RobinMétral Yeah, I sometimes find disclaimers ridiculous. I didn't post this for my own publicity but to genuinely help people with the same needs as me. `ts-node` was troubles and slowness and I wanted to have a modern typescript runner. I also consider it's not really my work since I've only written a small wrapper around the awesome EsBuild library from Evan W - he is the guy who deserves all the credits. – Gin Quin May 21 '21 at 09:19
  • Still – [you must disclose any affiliation](https://stackoverflow.com/help/promotion) in your answers. In this particular case, too, the library is far from a standard: single contributor, single test, few NPM downloads. esbuild is still a good recommendation I think, but I would recommend using it directly, or via another library like [Estrella](https://github.com/rsms/estrella) – Robin Métral May 21 '21 at 13:00
  • 3
    Oh thx for the link @RobinMétral, didn't know it was mandatory. I will update my answer. This library is nothing more than a 77-lines of code wrapper around Esbuild, no need for a 7-collaborators team or an extended test suite for 77 lines of code. All the work is done by Esbuild. People can use it or ts-node or sucrase-node or anything they prefer. I personnally prefer my library because I encountered less issues. Estrella looks awesome but I would not recommand it for this question (nor Esbuild) as they are both build tools and not running tools. – Gin Quin May 22 '21 at 19:11
  • 4
    I’m not sure why this wasn’t specified, but to (easily) use this do `npx @digitak/esrun index.ts` replacing `index.ts` if required. – mxcl Aug 26 '21 at 14:18
  • 2
    @GinQuin I just wanted to add my thanks for building this. I also found that ts-node doesn't work well with scripts that import/export. You have saved me alot of headaches. It's insane that typescript doesn't already have this functionality built-in to their tooling, so thank you for filling in the gaps. – Doomd Jan 11 '22 at 18:48
  • 1
    Same here. I've tried `ts-node` and `tsx` and `esrun` is the only one that just worked. Thanks so much! – mikemaccana Jan 17 '23 at 12:31
  • @GinQuin I posted about TS tools, mentioning `esrun` and Brendan Eich (creator of JavaScript) retweeted it to all his followers: https://twitter.com/mikemaccana/status/1617616516073271296?s=20&t=6FCBeQDRMcZJ07JKvXPvpw – mikemaccana Jan 24 '23 at 15:24
  • 1
    @mikemaccana Great! I hope many people will find esrun as useful as I do – Gin Quin Jan 25 '23 at 17:02
  • Thank you @GinQuin. Also on team `esrun` and have been using it with a few projects for the last few months. – dogeen Apr 20 '23 at 07:45
43

Edit: May 2022

ts-node now has an --esm flag use it.

Old Answer:

None of the other answers discuss how to run a TypeScript script that uses modules, and especially modern ES Modules.

First off, ts-node doesn't work in that scenario, as of March 2020. So we'll settle for tsc followed by node.

Second, TypeScript still can't output .mjs files. So we'll settle for .js files and "type": "module" in package.json.

Third, you want clean import lines, without specifying the .js extension (which would be confusing in .ts files):

import { Lib } from './Lib';

Well, that's non-trivial. Node requires specifying extensions on imports, unless you use the experimental-specifier-resolution=node flag. In this case, it would enable Node to look for Lib.js or Lib/index.js when you only specify ./Lib on the import line.

Fourth, there's still a snag: if you have a different main filename than index.js in your package, Node won't find it.

Transpiling makes things a lot messier than running vanilla Node.

Here's a sample repo with a modern TypeScript project structure, generating ES Module code.

bcbrian
  • 177
  • 2
  • 8
Dan Dascalescu
  • 143,271
  • 52
  • 317
  • 404
  • 3
    You can use https://www.npmjs.com/package/@digitak/esrun which solves the issues mentioned – Gin Quin Feb 15 '21 at 11:40
  • Thanks @GinQuin ! esrun did exactly what I expected ts-node to do: SImply run the script with imports. – vlz Oct 20 '21 at 17:07
  • Look for my answer ts-node now supports the `--esm` flag. You answer is my fav! Could you update to help future devs :) – bcbrian May 04 '22 at 18:22
  • Reviewer note: @bcbrian - there is no need to edit this information in since you posted an answer yourself. It is perfectly natural for new answers to contain updated information - take the credit. – Oleg Valter is with Ukraine May 05 '22 at 07:46
  • 1
    Adding --esm doesn't solve the required file extensions on imports issue. – Imran Sep 29 '22 at 06:49
41

You can also try tsx. tsx is a CLI command (alternative to node) for seamlessly running TypeScript, its build upon esbuild so its very fast.

https://github.com/esbuild-kit/tsx

Example:

npx tsx ./script.ts
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
20

Just helpful information - here is newest TypeScript / JavaScript runtime Deno.

It was created by the creator of node Ryan Dahl, based on what he would do differently if he could start fresh.

  • 5
    Here's an example: `deno run https://deno.land/std/examples/welcome.ts` – mozey May 15 '20 at 12:14
  • 1
    this would be my preferred approach, except for import/require issues with node modules, which is non-trivial to fix – hkong Feb 04 '21 at 15:52
  • As tools grow to support Deno's security, I see its ease of use increasing. Including how imports need to have the full relative path/url and file extension. `Deno is secure by default. Therefore, unless you specifically enable it, a deno module has no file, network, or environment access for example.` add the extra flags while developing. then lock it down: `deno run --unstable --allow-read --allow-env main.ts` -> https://dev.to/mxfellner/node-js-compatibility-using-npm-packages-in-deno-52hh – TamusJRoyce May 28 '21 at 12:43
11

For linux / mac you can add the ts-node-script shebang.

Install typescript / ts-node globally (see 1 below for non global install):

npm install ts-node typescript --save-dev --global

Add this as the first line in your .ts file:

#!/usr/bin/env ts-node-script

Then make the file executable:

$ chmod +x ./your-file.ts

You can then run the file directly from the command line:

$ ./your-file.ts

Notes:

1 For non global install you can install local to your project

npm install ts-node typescript --save-dev

and add the relative path to the shebang script eg:

#!/usr/bin/env ./node_modules/.bin/ts-node-script

2 Support for shebangs was officially added in ts-node v8.9.0.

robd
  • 9,646
  • 5
  • 40
  • 59
11

As of May 2022 ts-node does support es modules

npx ts-node --esm file.ts

you will likely need to add "type": "module", to your package.json. And some of the imports might be wonky unless you turn on experimental-specifier-resolution=node

npmjs.com/package/ts-node#commonjs-vs-native-ecmascript-modules

bcbrian
  • 177
  • 2
  • 8
7

Like Zeeshan Ahmad's answer, I also think ts-node is the way to go. I would also add a shebang and make it executable, so you can just run it directly.

  1. Install typescript and ts-node globally:

    npm install -g ts-node typescript
    

    or

    yarn global add ts-node typescript
    
  2. Create a file hello with this content:

    #!/usr/bin/env ts-node-script
    
    import * as os from 'os'
    
    function hello(name: string) {
        return 'Hello, ' + name
    }
    const user = os.userInfo().username
    console.log(`Result: ${hello(user)}`)
    

    As you can see, line one has the shebang for ts-node

  3. Run directly by just executing the file

    $ ./hello
    Result: Hello, root
    

Some notes:


Update 2020-04-06: Some changes after great input in the comments: Update shebang to use ts-node-script instead of ts-node, link to issues in ts-node.

Kariem
  • 4,398
  • 3
  • 44
  • 73
  • 3
    [`ts-node` doesn't support ES Modules](https://github.com/TypeStrong/ts-node/issues/935#issuecomment-579718641). – Dan Dascalescu Mar 05 '20 at 09:58
  • 1
    You can run into many problems with this approach. I documented potential solutions in [this issue](https://github.com/TypeStrong/ts-node/issues/995). In particular, the shebang `#!/usr/bin/env ts-node-script` (also part of `ts-node`) seems to be superior for this purpose. If you want to link your script (e.g. with [`npm link`](https://docs.npmjs.com/cli/link)), things get more complicated as the script mode of `ts-node` does not (yet?) follow symbolic links. I went with `#!/usr/bin/env -S ts-node --project /usr/local/lib/node_modules//tsconfig.json` in the end in my case. – Kaspar Etter Apr 03 '20 at 23:11
6

Write yourself a simple bash wrapper may helps.

#!/bin/bash
npx tsc $1 && node ${1%%.ts}
Joyer
  • 371
  • 2
  • 9
6

For environments such as Webstorm where the node command cannot be changed to ts-node or npx:

  1. npm install ts-node typescript (Install dependencies)
  2. node --require ts-node/register src/foo.ts (Add --require ts-node/register to "Node parameters")
Daniel T
  • 827
  • 9
  • 14
  • You *can* change the Node interpreter in WebStorm. In the Run/Debug configuration, you can select any binary you want as the Node interpreter. – Dan Dascalescu Feb 15 '21 at 13:18
4

This answer may be premature, but deno supports running both TS and JS out of the box.

Based on your development environment, moving to Deno (and learning about it) might be too much, but hopefully this answer helps someone in the future.

varagrawal
  • 2,909
  • 3
  • 26
  • 36
  • 1
    This answer is essentially a [duplicate of a 2018 one](https://stackoverflow.com/questions/33535879/how-to-run-typescript-files-from-command-line/53395121#53395121). – Dan Dascalescu Feb 15 '21 at 13:16
4

Here is the command

tsc index.ts --outDir .temp && node .temp/index.js && rm -rf .temp
<<<<<<<<< Compile >>>>>>>>> <<<<<<< Run >>>>>>> << Clean >>

3

Just in case anyone is insane like me and wants to just run typescript script as though it was a .js script, you can try this. I've written a hacky script that appears to execute the .ts script using node.

#!/usr/bin/env bash

NODEPATH="$HOME/.nvm/versions/node/v8.11.3/bin" # set path to your node/tsc

export TSC="$NODEPATH/tsc"
export NODE="$NODEPATH/node"

TSCFILE=$1 # only parameter is the name of the ts file you created.

function show_usage() {
    echo "ts2node [ts file]"
    exit 0
}

if [ "$TSCFILE" == "" ]
then
    show_usage;
fi

JSFILE="$(echo $TSCFILE|cut -d"." -f 1).js"

$TSC $TSCFILE && $NODE $JSFILE

You can do this or write your own but essentially, it creates the .js file and then uses node to run it like so:

# tsrun myscript.ts

Simple. Just make sure your script only has one "." else you'll need to change your JSFILE in a different way than what I've shown.

Harlin
  • 1,059
  • 14
  • 18
2
  1. Create your TypeScript file (ex. app.ts)
  2. npm i -D typescript ts-node -> to install the dev dependencies local
  3. npx nodemon app.ts

Using nodemon, automatically recompile app.ts every time you change the file

Vasilis Plavos
  • 230
  • 2
  • 8
2

Use bun.

It's faster and has a lot of tooling bundled in.

bun run ./my-script.ts

Xuan
  • 5,255
  • 1
  • 34
  • 30
1
  1. Install ts-node node module globally.
  2. Create node runtime configuration (for IDE) or use node in command line to run below file js file (The path is for windows, but you can do it for linux as well) ~\AppData\Roaming\npm\node_modules\ts-node\dist\bin.js
  3. Give your ts file path as a command line argument.
  4. Run Or Debug as you like.
Paramvir Singh Karwal
  • 597
  • 1
  • 10
  • 24
1

For someone who’s having issue with ESM & CJS compatibility issue, tsx is a great fit.

More details about why.

Allen
  • 4,431
  • 2
  • 27
  • 39
0

There is also an option to run code directly from the CLI, not the *.ts file itself.

It's perfectly described in the ts-node manual.

  1. As a first step, install ts-node globally via npm, yarn, or whatever you like.
  2. ...and now just use ts-node -e 'console.log("Hello, world!")' (you may also add the -p flag for printing code)

This little command is perfect for checking, does everything installed fine. And for finding some other error, relevant with tsconfig.json options.

AlexZeDim
  • 3,520
  • 2
  • 28
  • 64
-3

We can run it using nodemon as well

nodemon ./filepath/filename.ts
Deepak Yadav
  • 1,724
  • 3
  • 23
  • 38
-53

This question was posted in 2015. In 2018, node recognizes both .js and .ts. So, running node file.ts will also run.

Rahul Sharma
  • 2,867
  • 2
  • 27
  • 40
even2468
  • 1
  • 1
  • 33
    Node interprets any file as javascript, so it will only work if the typescript file in question is a valid javascript file itself. – Preda7or Mar 28 '18 at 15:49
  • 1
    This will work if file content is valid javascript but extension is ts. Node does not care what the extension is, as long as content is valid javascript. – snnsnn Apr 29 '20 at 09:53