aster the Right Way to Set Up TypeScript in Node.js

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!

Share this article

Similar Posts