1.2 Installation and Environment Setup
Getting started with TypeScript requires a few tools. The TypeScript compiler itself is distributed as a Node.js package, so a Node.js environment is a prerequisite. This chapter walks through the entire process of setting up a TypeScript development environment from scratch, step by step.
Verifying Your Node.js Installation
The TypeScript compiler (tsc) and related tools all run in a Node.js environment. Open a terminal and run the following commands to check whether Node.js is installed.
node -v
# Should be v20.x.x or higher
npm -v
# v10.x.x or higher recommended
If Node.js is not installed, download the LTS (Long Term Support) version from nodejs.org. TypeScript 5.x requires Node.js 14.17 or higher, but Node.js 20 LTS is the recommended choice for production use.
If you need to manage multiple Node.js versions, use nvm (Node Version Manager).
# Install Node.js 20 LTS via nvm
nvm install 20
nvm use 20
node -v # v20.x.x
How to Install TypeScript
There are two main approaches to installing TypeScript: globally and locally.
Global installation
Installs TypeScript so the tsc command is available anywhere on your system. Convenient for quick experiments and one-off scripts.
npm install -g typescript
# Verify installation
tsc -v
# Version 5.x.x
Local installation (recommended for real projects)
Installs TypeScript only inside the project directory. It gets recorded in devDependencies, so anyone who runs npm install will automatically get the exact same version.
npm install --save-dev typescript
# Check version (runs local tsc via npx)
npx tsc -v
# Version 5.x.x
Local installation is essential in real projects. When team members each have different versions installed globally, compilation results can diverge. Local installation combined with package.json scripts prevents this problem.
npx tsc — running the local tsc
npx is a tool for running the CLI of a locally installed package. When TypeScript is installed locally, use npx tsc instead of tsc directly.
npx tsc --version # Check local TypeScript version
npx tsc hello.ts # Compile the file hello.ts
npx tsc # Compile the whole project based on tsconfig.json
npx tsc --watch # Watch for file changes and recompile automatically
npx tsc --init # Generate a tsconfig.json file
Basic tsc Usage
Familiarizing yourself with the basic usage patterns of the TypeScript compiler helps you understand the development workflow.
Compiling a single file
tsc hello.ts
Compiles hello.ts and produces hello.js in the same directory. If there are type errors, the error messages are printed, but the .js file is still generated by default.
Compiling the whole project
Running tsc alone inside a directory that contains a tsconfig.json compiles the entire project according to that configuration file.
tsc
# Reads tsconfig.json and compiles according to its settings
Watch mode
During development, watch mode automatically recompiles whenever a file is saved.
tsc --watch
# or
tsc -w
The moment you save a file, the compilation result appears in the terminal immediately.
Type checking only
Checks for type errors without producing any JavaScript files. Commonly used in CI/CD pipelines.
tsc --noEmit
ts-node — Running TypeScript Directly
tsc compiles TypeScript to JavaScript, which then needs to be run separately with node — two steps every time. ts-node combines these two steps into one, allowing you to execute TypeScript files directly.
Installing ts-node
# Global installation
npm install -g ts-node
# Local installation (recommended)
npm install --save-dev ts-node
Using ts-node
# Run a TypeScript file directly
ts-node src/index.ts
# When installed locally
npx ts-node src/index.ts
How ts-node works
ts-node calls the TypeScript compiler internally, compiles the code in memory, and executes it immediately — no .js files are written to disk. This creates a fast feedback loop during development.
The downside is speed. Compile time can be noticeable in large projects. It also has limited support for the latest TypeScript 5.x features and ESM (ES Modules) in some cases.
tsx — A Faster Alternative
tsx is a faster alternative to ts-node. It uses esbuild internally to transform TypeScript. esbuild is a bundler written in Go that is tens of times faster than traditional JavaScript-based tools.
Installing tsx
# Global installation
npm install -g tsx
# Local installation (recommended)
npm install --save-dev tsx
Using tsx
# Run a TypeScript file directly
tsx src/index.ts
# Watch mode (reruns automatically when files change)
tsx watch src/index.ts
# When installed locally
npx tsx src/index.ts
Advantages of tsx
tsx supports ESM (ES Modules) natively. You can run modern code that uses import/export syntax without any additional configuration. Because it only transforms code without performing type checking, it is extremely fast.
The important caveat is that tsx skips type checking entirely. It will execute code even if type errors are present. Type safety must be verified separately using tsc --noEmit.
ts-node vs tsx Comparison
| Aspect | ts-node | tsx |
|---|---|---|
| Execution speed | Slow | Fast (esbuild-based) |
| Type checking | Performed | Skipped |
| ESM support | Requires configuration | Supported by default |
| CJS support | Supported by default | Supported |
| Watch mode | Supported | Supported via tsx watch |
| Reflects tsconfig | Yes | Yes |
| Primary use case | Development / scripts | Development / scripts |
If you want fast feedback during development, tsx is the recommended choice. Handle type checking separately with your IDE and tsc --noEmit.
Project Initialization Workflow
Let's walk through the complete process of creating a new TypeScript project from scratch.
Step 1: Create the directory and initialize npm
mkdir my-ts-project
cd my-ts-project
npm init -y
npm init -y accepts all defaults and immediately creates package.json.
Step 2: Install dependencies
npm install --save-dev typescript tsx @types/node
typescript: The TypeScript compilertsx: Fast TypeScript execution tool@types/node: Type definitions for Node.js built-in modules (fs,path,process, etc.)
Step 3: Generate tsconfig.json
npx tsc --init
This creates tsconfig.json in the project root. The file contains hundreds of lines, most of which are commented out — only a handful of options are active by default.
Step 4: Create the directory structure
mkdir src dist
Source files go in src/, compiled output goes in dist/.
Step 5: Add package.json scripts
Open package.json and update the scripts section.
{
"scripts": {
"build": "tsc",
"build:watch": "tsc --watch",
"dev": "tsx watch src/index.ts",
"start": "node dist/index.js",
"type-check": "tsc --noEmit"
}
}
You can now use these commands to drive your development workflow.
npm run dev # Development server (tsx watch, fast execution)
npm run build # Production build (tsc compilation)
npm run type-check # Check for type errors only
Step 6: Write the initial source file
// src/index.ts
const message: string = "TypeScript project is up and running!";
console.log(message);
Final project structure
my-ts-project/
├── src/
│ └── index.ts # TypeScript source file
├── dist/ # Compiled output (generated automatically)
│ └── index.js
├── node_modules/
├── package.json
├── package-lock.json
└── tsconfig.json
Practical Example: Setting Up a Simple TypeScript Project
Let's build a fully working project environment from scratch.
# 1. Initialize project
mkdir ts-starter && cd ts-starter
npm init -y
# 2. Install dependencies
npm install --save-dev typescript tsx @types/node
# 3. Generate tsconfig.json
npx tsc --init
# 4. Create source directory
mkdir src
Configure the key options in tsconfig.json.
{
"compilerOptions": {
"target": "ES2022",
"module": "CommonJS",
"rootDir": "./src",
"outDir": "./dist",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
Add scripts to package.json.
{
"name": "ts-starter",
"version": "1.0.0",
"scripts": {
"dev": "tsx watch src/index.ts",
"build": "tsc",
"start": "node dist/index.js",
"type-check": "tsc --noEmit"
},
"devDependencies": {
"@types/node": "^20.0.0",
"tsx": "^4.0.0",
"typescript": "^5.0.0"
}
}
Write the first source file.
// src/index.ts
interface Person {
name: string;
age: number;
}
function greet(person: Person): string {
return `Hello, ${person.name}! You are ${person.age} years old.`;
}
const user: Person = {
name: "Alice",
age: 28,
};
console.log(greet(user));
Run it.
npm run dev
# Hello, Alice! You are 28 years old.
Produce a production build.
npm run build
# dist/index.js is generated
node dist/index.js
# Hello, Alice! You are 28 years old.
Pro Tips
Pin the TypeScript version per project
Pin the TypeScript version precisely in package.json so every team member uses exactly the same version.
{
"devDependencies": {
"typescript": "5.4.5"
}
}
Using a caret like ^5.0.0 allows minor updates to be applied automatically. TypeScript can change type checking behavior even across minor versions, so pinning an exact version is the safer choice in production projects.
tsx does not perform type checking
Just because code runs successfully with tsx does not mean the types are correct. tsx will execute code even when type errors exist. Always run tsc --noEmit separately before CI/CD or deployment to verify type safety.
{
"scripts": {
"dev": "tsx watch src/index.ts",
"type-check": "tsc --noEmit",
"build": "npm run type-check && tsc"
}
}
This pattern runs type checking first and only proceeds to compilation if it passes.
Add compiled output to .gitignore
# .gitignore
node_modules/
dist/
*.js.map
The dist/ folder is automatically generated from source code, so it doesn't need to be version-controlled. It can always be regenerated with npm run build.
Summary
| Tool | Installation | Purpose |
|---|---|---|
typescript | npm i -D typescript | TypeScript compiler (tsc) |
ts-node | npm i -D ts-node | Run TS directly (with type checking) |
tsx | npm i -D tsx | Run TS fast (type checking skipped) |
@types/node | npm i -D @types/node | Node.js type definitions |
npx tsc --init | — | Generate tsconfig.json |
tsc --watch | — | Watch for changes and recompile |
tsc --noEmit | — | Type check only, no output |
The next chapter takes a close look at the key options inside tsconfig.json.