Node.js TypeScript Setup — Complete Guide
In this tutorial, you will learn about Node.js TypeScript Setup. We cover key concepts, practical examples, and best practices to help you master this topic.
Setting up Node.js with TypeScript requires configuring the compiler for Node.js module systems, installing Node.js type definitions, and choosing a runtime (ts-node, tsx, or compiled output) for development and production.
What You'll Learn
- Installing @types/node
- ts-node vs tsx for development
- ESM vs CJS configuration
- Production build setup
- Debugging Node.js TypeScript
Why It Matters
Node.js without TypeScript is error-prone — fs.readFileSync returns Buffer | string, callback parameters are untyped, and configuration files lack autocompletion. TypeScript brings the same safety to the backend as it does to the frontend.
Real-World Use
Every DodaTech backend service — from the Durga Antivirus Pro API server to the Doda Browser sync service — is written in TypeScript and runs on Node.js. The standard setup uses tsx for development and compiled JS for production.
Learning Path
flowchart LR A[React Advanced] --> B[Node Setup] B --> C[Express APIs] B --> D[You Are Here] C --> E[Next.js] E --> F[NestJS]
Installing Dependencies
mkdir my-api && cd my-api
npm init -y
npm install --save-dev typescript @types/node tsx
@types/node provides type definitions for all Node.js built-in modules (fs, path, http, etc.).
tsconfig for Node.js
{
"compilerOptions": {
"target": "ES2022",
"module": "Node16",
"moduleResolution": "Node16",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"outDir": "./dist",
"rootDir": "./src",
"sourceMap": true,
"declaration": true
},
"include": ["src"]
}
Development with tsx
tsx (TypeScript Execute) runs TypeScript directly without compilation:
npm install --save-dev tsx
// package.json
{
"scripts": {
"dev": "tsx watch src/index.ts",
"build": "tsc",
"start": "node dist/index.js"
}
}
// src/index.ts
import { readFile, writeFile } from 'fs/promises';
import { join } from 'path';
async function readConfig(): Promise<Record<string, unknown>> {
const configPath = join(process.cwd(), 'config.json');
const content = await readFile(configPath, 'utf-8');
return JSON.parse(content);
}
async function main() {
const config = await readConfig();
console.log('Server starting with config:', config);
}
main().catch(console.error);
ESM vs CJS
ESM (Recommended for new projects)
// package.json
{
"type": "module"
}
// Must use import/export syntax
import { readFile } from 'fs/promises';
// Import with .js extension (even for .ts files with Node16 resolution)
CJS (Legacy or specific requirements)
// package.json
{
"type": "commonjs"
}
// import/export compiles to require/module.exports
import { readFile } from 'fs/promises';
Production Build
npm run build
# Outputs to dist/:
# - Compiled JS files
# - Source maps
# - Declaration files (.d.ts)
{
"scripts": {
"build": "tsc",
"start": "node --enable-source-maps dist/index.js",
"dev": "tsx watch src/index.ts"
}
}
Debugging
VS Code Launch Configuration
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Debug API",
"runtimeExecutable": "npx",
"runtimeArgs": ["tsx"],
"args": ["src/index.ts"],
"console": "integratedTerminal",
"sourceMaps": true
}
]
}
Environment Variables
// src/config.ts
import 'dotenv/config';
interface AppConfig {
port: number;
databaseUrl: string;
apiKey: string;
nodeEnv: 'development' | 'production' | 'test';
}
function getConfig(): AppConfig {
return {
port: parseInt(process.env.PORT || '3000', 10),
databaseUrl: process.env.DATABASE_URL || 'postgres://localhost:5432/app',
apiKey: process.env.API_KEY || '',
nodeEnv: (process.env.NODE_ENV as AppConfig['nodeEnv']) || 'development',
};
}
export const config = getConfig();
Common Mistakes
1. Forgetting @types/node
Without it, fs, path, http, and other Node.js modules are typed as any.
2. Wrong Module Resolution for Node.js
Use Node16 or NodeNext for modern Node.js projects. bundler resolution may not work correctly with Node.js module system.
3. Using ts-node Instead of tsx
ts-node is slower and has compatibility issues. tsx is faster and supports ESM natively.
4. Not Adding type: "module" for ESM
Without it, Node.js treats .js files as CJS even if TypeScript outputs ESM syntax.
5. Hardcoding Configuration
Always use environment variables or config files managed by the deployment environment.
Practice Questions
What does
@types/nodeprovide? Type definitions for Node.js built-in modules (fs, path, http, process, etc.).What is the difference between
tsxandts-node? tsx is faster, uses esbuild, supports ESM natively. ts-node is slower and has compatibility issues.Why use
Node16module resolution? It matches Node.js's native module resolution, supporting both ESM and CJS with correct extensions.What does
tsx watchdo? Runs TypeScript files and automatically restarts when files change.
Challenge: Set up a Node.js TypeScript project with ESM, dotenv, and a production build pipeline. Create a simple HTTP server that reads environment variables and returns them as JSON.
FAQ
Mini Project: TypeScript Node.js Server
// src/server.ts
import { createServer, IncomingMessage, ServerResponse } from 'http';
import { readFile } from 'fs/promises';
import { join, extname } from 'path';
const PORT = parseInt(process.env.PORT || '3000', 10);
const MIME_TYPES: Record<string, string> = {
'.html': 'text/html',
'.js': 'text/javascript',
'.css': 'text/css',
'.json': 'application/json',
};
async function handleRequest(req: IncomingMessage, res: ServerResponse): Promise<void> {
try {
const url = req.url === '/' ? '/index.html' : req.url!;
const filePath = join(process.cwd(), 'public', url);
const ext = extname(filePath);
const content = await readFile(filePath);
res.writeHead(200, { 'Content-Type': MIME_TYPES[ext] || 'text/plain' });
res.end(content);
} catch {
res.writeHead(404, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'Not found' }));
}
}
const server = createServer(handleRequest);
server.listen(PORT, () => console.log(`Server running on http://localhost:${PORT}`));
What's Next
Now build typed Express APIs:
| Lesson | Description |
|---|---|
| {{< ref "/programming-languages/typescript/42-react-advanced" >}} | Review React advanced |
| {{< ref "/programming-languages/typescript/44-express-apis" >}} | Express with typed middleware and requests |
| {{< ref "/programming-languages/typescript/45-nextjs" >}} | Next.js App Router with TypeScript |
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro