Setting up a TypeScript project with Node.js may seem like a hassle at first, but with the right steps, you'll have everything running smoothly in no time. Whether you're building a small script or a full-fledged application, this guide will walk you through the entire process.
We'll start from scratch, configure TypeScript, and set up a simple development environment with best practices. Let's dive in!
Setup Node.js Project
First, you need a dedicated folder for your project. Open your terminal and run the following commands:
// Command Linemkdir my-projectcd my-projectnpm init -y
Let's break down what each command does:
mkdir my-project
: Creates a new project directory.cd my-project
: Moves into the new directory.npm init -y
: Initializes a newpackage.json
file with default values.
This package.json
file is essential for a Node.js project as it manages dependencies and scripts for your project.
TypeScript in Node.js
Now, let's install TypeScript as a development dependency and create a configuration file:
// Command Linenpm install --save-dev typescripttouch tsconfig.json
Let's break down what each command does:
npm install --save-dev typescript
: Installs TS locally for your project.touch tsconfig.json
: Creates a TypeScript configuration file.
Next, add the following configuration to your tsconfig.json
file:
// tsconfig.json{"compilerOptions": {/* Modern JavaScript & Browser Compatibility: */"target": "ESNext", // Uses the latest ECMAScript features for modern JavaScript support/* Module System Settings: */"module": "NodeNext", // Configures Node.js to use ESM module system"rootDir": "src", // Specifies the source directory for your code"outDir": "dist", // Specifies the output directory for compiled files"sourceMap": true, // Enables source maps for easier debugging/* Module Resolution Strategy: */"moduleResolution": "NodeNext", // Resolves modules using Node’s ESM strategy"moduleDetection": "force", // Forces TypeScript to treat files as modules/* Interoperability and File Consistency: */"esModuleInterop": true, // Ensures compatibility between CommonJS and ESM modules"forceConsistentCasingInFileNames": true, // Prevents case-sensitivity issues across platforms/* Strict Type-Checking: */"strict": true, // Enables strict type-checking for fewer runtime errors"noUncheckedIndexedAccess": true, // Enforces type safety for array/object accesses"noImplicitOverride": true, // Enforces explicit use of `override` for methods overriding base class methods"noImplicitAny": true, // Prevents the use of `any` type unless explicitly defined"skipLibCheck": true, // Skips type-checking of declaration files for faster compilation"resolveJsonModule": true, // Allows importing JSON files as modules"declaration": true, // Generates `.d.ts` files for type definitions"allowSyntheticDefaultImports": true, // Allows default imports for CommonJS modules"allowImportingTsExtensions": true, // Allows importing `.ts` files with their extensions"verbatimModuleSyntax": true, // Keeps the `import`/`export` syntax as-is without transformation// Include modern ECMAScript (ES2022) and DOM APIs for frontend"lib": ["ES2022", "DOM"] // Include ES2022 features and DOM APIs for frontend development// Uncomment this for backend code without DOM APIs/* "lib": ["ES2022"] */},"include": ["src"], // Includes the `src` directory in the project"exclude": ["node_modules", "dist"] // Excludes `node_modules` and `dist` directories from the project}
Optionally add the following lines for JavaScript support in a TypeScript project:
// tsconfig.json{"compilerOptions": {..."allowJs": true,"checkJs": true}}
If we are fully committing to ESM, add this to the package.json
:
{"type": "module"}
Source Folder and Entry File
Create a src
folder and an index.ts
file inside it:
// Command Linemkdir srctouch src/index.ts
Now, add a simple TypeScript script in src/index.ts
:
// src/index.tsconsole.log("Hello world!");
This will serve as our starting point to ensure everything is working correctly.
Run & Compile TypeScript Files in Node.js
To run TypeScript files directly without compiling them first, install tsx
which is a popular TypeScript runner. An alternative would be to use ts-node
:
// Command Linenpm install tsx --save-dev
You can also use type stripping natively in Node.js, but tsx
fully supports TypeScript features. Now, update your package.json
scripts to use tsx
:
// package.json"scripts": {"dev": "tsx src/index.ts","build": "tsc","start": "node dist/index.js"}
Let's break down what each script does:
"dev": "tsx src/index.ts"
:- Runs the project in development mode using
tsx
. This script is used during development.
- Runs the project in development mode using
"build": "tsc"
:- Compiles TypeScript files into JavaScript with TypeScript compiler (
tsc
). The compiled files are stored in thedist
folder.
- Compiles TypeScript files into JavaScript with TypeScript compiler (
"start": "node dist/index.js"
:- Runs the compiled JavaScript files. This script is used in production.
For automatic reloading, update the dev
script:
// package.json"scripts": {"dev": "tsx --watch src/index.ts","build": "tsc","start": "node dist/index.js"}
The --watch
flag makes tsx
automatically recompile and reload files when changes are made.
Environment Variables in Node.js
Many applications require sensitive API keys and environment variables. The best practice is to store them in a .env
file instead of hardcoding them. Create a .env
file in your project directory with the following content:
# .envOPENAI_API_KEY="sk-proj-123abc"
Then, modify src/index.ts
to read the environment variable:
// src/index.tsconsole.log(process.env.OPENAI_API_KEY);
To ensure environment variables are recognized by TypeScript, install Node.js type definitions:
// Command Linenpm install @types/node --save-dev
If you're using Node.js 20.6.0 or newer, you can load environment variables directly using the --env-file
flag:
// package.json"scripts": {"dev": "tsx --watch --env-file=.env src/index.ts","build": "tsc","start": "node --env-file=.env dist/index.js"}
For a more sophisticated approach, consider using the dotenv
package:
// Command Linenpm install dotenv
Modify src/index.ts
to load the .env
file using dotenv
:
// src/index.tsimport "dotenv/config";console.log(process.env.OPENAI_API_KEY);
Update the package.json
scripts accordingly:
// package.json"scripts": {"dev": "tsx --watch src/index.ts","build": "tsc","start": "node dist/index.js"}
Now, your project can securely read environment variables.
That's it! You've successfully set up a TypeScript project with Node.js. Here's a quick recap of what we did:
- Created a new Node.js project with
npm init
- Installed and configured TypeScript
- Set up a source directory with a TypeScript entry file
- Installed
tsx
for running TypeScript files efficiently - Configured environment variables using
.env
- Used
dotenv
for better environment variable management
Now you're ready to start building your TypeScript-powered Node.js application!