Installation & Setup
TypeScript is a superset of JavaScript that adds static type checking. Before you can write TypeScript code, you need to install the compiler and configure your project. This guide walks you through every step — from a bare machine to a fully working TypeScript environment.
Prerequisites
TypeScript runs on top of Node.js, so you need Node.js installed first. TypeScript itself is just an npm package that ships the tsc compiler.
Node.js 18 or higher (LTS recommended)
npm 9+ (bundled with Node) or yarn / pnpm
A code editor — VS Code has the best TypeScript integration out of the box
node -v and your npm version with npm -v in a terminal.Installing Node.js
If you don't have Node.js yet, the easiest approach is via the official installer or a version manager.
Method | Best For | Command / Link |
|---|---|---|
Official installer | Beginners, one-time setup | nodejs.org/en/download |
nvm (Node Version Manager) | Switching between Node versions | nvm install --lts |
fnm (Fast Node Manager) | Speed-focused, Rust-based | fnm install --lts |
Homebrew (macOS) | macOS users who already use brew | brew install node |
# Install nvm (macOS / Linux) curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash # Install the latest LTS Node nvm install --lts nvm use --lts # Verify node -v # e.g. v20.11.0 npm -v # e.g. 10.2.4
Installing TypeScript
There are two ways to install TypeScript: globally (available everywhere on your machine) or locally (per project). The recommended approach is a local installation so every project pins its own TypeScript version.
Global Installation
npm install -g typescript # Confirm the compiler is available tsc --version # e.g. Version 5.4.5
Local Installation (recommended)
mkdir my-ts-project cd my-ts-project npm init -y # creates package.json npm install --save-dev typescript # installs TypeScript locally # Run the locally installed compiler via npx npx tsc --version
Initializing tsconfig.json
tsconfig.json is the heart of every TypeScript project. It tells the compiler where your source files are, what JavaScript version to target, and how strictly to type-check your code.
npx tsc --init
This generates a tsconfig.json with every option commented out. Here is a clean, well-explained starter config for a modern Node.js or browser project:
{
"compilerOptions": {
/* Language & output */
"target": "ES2020", // compile to ES2020 JavaScript
"module": "CommonJS", // Node.js module format (use "ESNext" for bundlers)
"lib": ["ES2020", "DOM"], // built-in type definitions to include
/* Paths */
"rootDir": "./src", // your TypeScript source lives here
"outDir": "./dist", // compiled JS goes here
/* Strictness */
"strict": true, // enables all strict checks — highly recommended
/* Module resolution */
"esModuleInterop": true, // saner default/named import behaviour
"resolveJsonModule": true, // allow importing .json files
"moduleResolution": "node",
/* Quality of life */
"sourceMap": true, // .map files for debugging
"declaration": true, // emit .d.ts for library authors
"skipLibCheck": true // skip type-checking inside node_modules
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}strict flag is a shorthand that enables strictNullChecks, noImplicitAny, strictFunctionTypes, and several other checks simultaneously. Always start new projects with it enabled.Your First TypeScript File
Create the source directory, then write a simple TypeScript file:
mkdir src touch src/index.ts
// src/index.ts
function greet(name: string): string {
return `Hello, ${name}!`;
}
const message = greet('TypeScript');
console.log(message);Compiling to JavaScript
npx tsc # The compiler reads tsconfig.json and produces: # dist/index.js # dist/index.js.map # dist/index.d.ts node dist/index.js
Hello, TypeScript!
Watch Mode
Recompiling manually after every save is tedious. Pass --watch (or -w) to make the compiler recompile automatically whenever a file changes.
npx tsc --watch
[12:00:00] Starting compilation in watch mode... [12:00:01] Found 0 errors. Watching for file changes.
ts-node and tsx: Run TypeScript Directly
During development you often want to run TypeScript without a separate compile step. ts-node handles that by compiling files on-the-fly in memory. tsx is a faster alternative that uses esbuild under the hood.
# Option A — ts-node npm install --save-dev ts-node npx ts-node src/index.ts # Option B — tsx (faster, recommended) npm install --save-dev tsx npx tsx src/index.ts
Hello, TypeScript!
Adding npm Scripts
Add convenience scripts to package.json so the whole team uses the same commands:
{
"scripts": {
"build": "tsc",
"build:watch": "tsc --watch",
"start": "node dist/index.js",
"dev": "tsx watch src/index.ts",
"type-check": "tsc --noEmit"
}
}npm run build — compile once to dist/
npm run dev — run with live reload via tsx
npm run type-check — type-check without emitting files (great for CI)
VS Code Setup
VS Code ships with a built-in TypeScript language service. A few extensions make the experience even better:
ESLint — real-time lint errors in the editor
Prettier — code formatting on save
Error Lens — shows type errors inline next to the offending line
TypeScript Error Translator — converts cryptic TS errors into plain English
Path Intellisense — autocompletes import paths
// .vscode/settings.json
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}Setting Up ESLint + Prettier
TypeScript handles type checking; ESLint and Prettier handle code style. They complement each other perfectly.
npm install --save-dev eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin prettier eslint-config-prettier
// .eslintrc.json
{
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint"],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"prettier"
],
"rules": {
"@typescript-eslint/no-explicit-any": "warn",
"@typescript-eslint/no-unused-vars": "error"
}
}// .prettierrc
{
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "all",
"printWidth": 100
}Complete Project Structure
my-ts-project/ ├── src/ │ └── index.ts ├── dist/ ← generated, git-ignored │ ├── index.js │ ├── index.js.map │ └── index.d.ts ├── node_modules/ ← git-ignored ├── .eslintrc.json ├── .prettierrc ├── .vscode/ │ └── settings.json ├── .gitignore ├── package.json └── tsconfig.json
# .gitignore node_modules/ dist/
Strict Mode Options Explained
"strict": true is a shorthand for enabling all of the following flags simultaneously:
Flag | What it prevents |
|---|---|
strictNullChecks | Using null/undefined where a concrete value is expected |
noImplicitAny | Variables and parameters inferred as |
strictFunctionTypes | Unsafe function parameter variance |
strictBindCallApply | Wrong argument types in .bind / .call / .apply |
strictPropertyInitialization | Class properties that might never be assigned |
noImplicitThis | Using |
alwaysStrict | Emits "use strict" in every output file |
strict: true enabled from day one will produce many errors. Use strict: false initially and enable individual flags one at a time as you fix each category of issue.Verifying Everything Works
Run npm run build — should produce files in dist/ with zero errors
Run npm run type-check — should report 0 errors
Run npm run dev — should execute and print output
Introduce a deliberate type error and confirm the compiler catches it
// Intentional error — tsc should reject this
function add(a: number, b: number): number {
return a + b;
}
add(1, 'two'); // Error: Argument of type 'string' is not assignable to type 'number'src/index.ts:6:8 - error TS2345: Argument of type 'string' is not
assignable to parameter of type 'number'.
add(1, 'two');
~~~~~
Found 1 error in src/index.ts:6Summary
Install Node.js first, then TypeScript as a local dev dependency per project
Run npx tsc --init to generate tsconfig.json, then enable strict mode
Use npx tsc --watch during development to see errors in real time
Use tsx to run TypeScript files directly without a separate build step
VS Code gives you intellisense, hover types, and inline errors for free
ESLint + Prettier catch style issues that the type checker ignores