DEV Community

Cover image for Typescript scripts in the command line: Using Node.JS
Renato Rodrigues
Renato Rodrigues

Posted on

Typescript scripts in the command line: Using Node.JS

In the previous article in this series, we saw how to implement an example Typescript script in Deno 2.0 and run it from the command line. In this article, for the sake of comparison, we will see how to achieve the same using Node.JS

Node.JS and Typescript support

Before starting, let's demystify one thing. Node.JS, at the time of writing, DOES NOT support Typescript. You may have seen some headlines recently stating that, but actually, what Node has is something called Typescript type stripping, which, as the name implies, just strips the Typescript portion of the code and interprets the remaining as regular Javascript code, ignoring any TS feature on it.

Type stripping was implemented first as an experimental flag on Node 22 and will be enabled by default on Node 23. It is also currently not complete and lacks support for some Typescript features, like ENUMS and Namespaces.

For these reasons, I like to think that Node.JS, in its current state, more likely tolerates (and ignores) Typescript than actually supports it.

Implementing the Script Using Node.JS

Initializing the project

First of all, we need to create a new folder and then initialize a Node.JS project there. For this, type in a Terminal window

mkdir sayHello
cd sayHello
npm init -y
Enter fullscreen mode Exit fullscreen mode

Installing the external dependencies

To use external dependencies (NPM modules) in Node.JS, we must first install them and then add them to our script.

Install chalk, yosay and inquirer from NPM by typing in the Terminal window

npm install chalk yosay inquirer
Enter fullscreen mode Exit fullscreen mode

Creating the script

Inside the sayHello folder, create a new folder called src, and inside it, a file called sayHello.ts.

mkdir src
touch src/sayHello.ts
Enter fullscreen mode Exit fullscreen mode

Importing the external dependencies

Import the dependencies to the script by opening src/sayHello.ts in your editor and add the following lines

// src/sayHello.ts

import chalk from 'chalk';
import yosay from 'yosay';
import inquirer, { Answers } from 'inquirer';
Enter fullscreen mode Exit fullscreen mode

Implementing the script body

With the dependencies added, it's time to implement the script body. For this, add the following lines to src/sayHello.ts after the import block

// src/sayHello.ts
// import ...

console.log(chalk.blue('\nHello visitor, please enter you details:\n'));

const questions: Answers = [
  {
    type: 'input',
    name: 'name',
    message: "What's your name?",
    required: true,
  },
  {
    type: 'list',
    name: 'salutation',
    message: 'How should I refer to you?',
    choices: ['Mr.', 'Mrs.', 'none'],
  }
];

inquirer.prompt(questions).then((answers) => {
  const { salutation, name } = answers ;

  console.log(`\n${chalk.green('[SUCCESS]:')} information entered was correct`);

  const person: string[] = [ name ];
  if(salutation !== 'none') person.unshift(salutation);

  console.log(yosay(`Hallo ${person.join(' ')}!`));
});

Enter fullscreen mode Exit fullscreen mode

Save the changes, and next, we will run the script.

Running the script from source

OK, now we have the script ready, but how do we run it? That's where things get a bit more complicated. In Node.JS, the short answer is that we cannot run it directly. You need to transpile it before running or use a dedicated tool to do it transparently for us. (again, ignore Node's type stripping feature)

So how do we run it then?

First of all, install the TSX dependency. In the terminal window, do

npm install --save-dev tsx
Enter fullscreen mode Exit fullscreen mode

Then, we have three ways of running the script from source.

Method 1: Using NPX

On the sayHello folder, do

npx tsx src/sayHello.ts
Enter fullscreen mode Exit fullscreen mode

It will use a tool called TSX to transpile and run the TS code transparently

Method 2: Adding an alias to package.json

Open the package.json file in your editor and add this line into the scripts section.

{
    "scripts": {
        "test": "...", // existing script
        "start": "tsx src/sayHello.ts"
    }
}
Enter fullscreen mode Exit fullscreen mode

then, on sayHello folder, just do

npm start

Enter fullscreen mode Exit fullscreen mode

Method 3: Making the script executable (Linux/MacOS)

Add this line at the top of src/sayHello.ts

#!/usr/bin/env -S npx tsx

// src/sayHello.ts
// ...
Enter fullscreen mode Exit fullscreen mode

open a Terminal window and run

chmod +x src/sayHello.ts
Enter fullscreen mode Exit fullscreen mode

and then, every time you need to run the script, in the sayHello folder, do

./src/sayHello.ts
Enter fullscreen mode Exit fullscreen mode

Run the script using the desired method, answer the questions, and check the output.

Going Further

Following the above steps, we were able to implement and run the same script we had in Deno 2.0. But there is one major difference. While Deno is truly running the script as-is, Node.JS, runs a transformed version of it that TSX generates. Let's say we have two versions of the script, the one we developed (in TS) and the other that Node runs natively (converted from TS to JS by TSX).

What are the implications? For big and complex projects, it could make things slower and require more resources, but for a small command line script, I would say none, if any at all.

What if I want to run the "translated" version of the script in Node and run it natively? Is it possible? Yes, it is, and this process we call transpilation, it's a bit complex topic and out of the scope of this article, so we are not covering it now. We may have it covered in an appendix after finishing this series. Stay tuned for more information.

Wrapping up

That's it. That's all we need to know to run a Typescript script with external dependencies, on the command line, using Node.JS

You can check the complete source code of the Node.JS version of the script here as well the source code of the Deno 2.0 version.

In the next article of our series, we’ll summarize both implementations and wrap up our findings with a thoughtful conclusion.

Top comments (0)