TypeScript in Node.js: A Solid Setup for Scalable Projects
Setting up a new Node.js project with TypeScript, testing, and modern tooling can be challenging. This guide walks you through the steps to establish a solid, scalable, and type-safe foundation from the very beginning.
🚀 Complete JavaScript Guide (Beginner + Advanced)
🚀 NodeJS – The Complete Guide (MVC, REST APIs, GraphQL, Deno)
Step 1: Project Initialization and Core Dependencies
We start in an empty project folder. Use npm to initialize the project and install the necessary development dependencies.
We’re installing typescript, @types/node (type definitions for Node.js), and importantly, @tsconfig/node22 to extend our configuration from the latest Long-Term Support (LTS) version of Node.js.
# Initialize the project npm init -y # Install core development dependencies npm install typescript @types/node @tsconfig/node24 --save-dev
Step 2: Configure TypeScript (tsconfig.json)
Create a tsconfig.json file in the root of your project to define how the TypeScript compiler should work.
We extend the base configuration, specify the source (rootDir: "src") and output (outDir: "dist") directories, and ensure case consistency across platforms.
// tsconfig.json
{
"extends": "@tsconfig/node22/tsconfig.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": "src",
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"]
}
The "include": ["src/**/*"] option tells TypeScript to compile all files within the src folder.
Step 3: Integrate Testing with Jest and ts-jest
A robust project requires testing. We’ll use Jest as our testing framework and ts-jest to process TypeScript files before running tests.
# Install testing dependencies npm install jest ts-jest @types/jest --save-dev
Create a jest.config.mjs file to configure Jest for our Node.js and TypeScript environment.
// jest.config.mjs
export default {
preset: 'ts-jest',
testEnvironment: 'node',
roots: ['<rootDir>/src'],
transform: {
'^.+\\.ts?$': 'ts-jest',
},
testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.ts?$',
moduleFileExtensions: ['ts', 'js', 'json', 'node'],
};
Step 4: Configure ESLint and Prettier for Code Quality
We use ESLint for linting and Prettier for consistent code formatting.
First, initialize ESLint (following the prompts to select Node, TypeScript, and no framework), and then install the necessary packages for Prettier integration and Jest linting.
# Initialize ESLint (follow prompts) npm init @eslint/config@latest # Install Prettier and Jest integration packages npm install prettier eslint-plugin-prettier eslint-config-prettier eslint-plugin-jest --save-dev
Update your eslint.config.mjs file to use the modern flat configuration format, integrating configurations for Node, TypeScript, Jest, and finally, Prettier (which must be last to correctly override formatting rules).
// eslint.config.mjs
import globals from 'globals';
import pluginJs from '@eslint/js';
import tseslint from 'typescript-eslint';
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
import jest from 'eslint-plugin-jest';
export default [
{ files: ['**/*.{js,mjs,cjs,ts}'] },
{ languageOptions: { globals: globals.node } },
pluginJs.configs.recommended,
...tseslint.configs.recommended,
{
files: ['src/tests/**/*.{ts}'],
...jest.configs.recommended,
},
{
rules: {
// Add your custom rules here, e.g. turning off rules that conflict with your style
},
},
eslintPluginPrettierRecommended,
];
Step 5: Define Scripts in package.json
Add scripts to your package.json for running tests, linting, building, and automating the development process.
// package.json (scripts section)
"scripts": {
"test": "jest",
"lint": "eslint .",
"build": "tsc",
"dev": "dotenv -- tsc-watch --onsuccess \"node dist/index.js\""
},
The "dev" script requires two additional dependencies: tsc-watch (to watch for file changes, recompile, and re-run) and dotenv-cli (to load environment variables during development).
# Install development automation tools npm install tsc-watch dotenv-cli --save-dev
Step 6: Finalizing with Git
To ensure version control and a clean repository, create a .gitignore file to exclude generated files and modules.
# .gitignore dist node_modules .env
Initialize your repository and create your first commit:
git init git add . git commit -m "initial commit: basic typescript node setup with jest and eslint"
You now have a production-ready Node.js and TypeScript boilerplate with comprehensive tooling for testing, linting, and a streamlined development experience. Happy coding!