Tutorials Logic, IN info@tutorialslogic.com

tsconfig.json Explained: Strict TypeScript Project Configuration

What Is tsconfig.json?

tsconfig.json tells TypeScript which files belong to a project and how the compiler should check or emit code. Most real TypeScript projects have one because compiler behavior should be consistent for every developer and every build.

Without a config file, you can compile individual files manually, but that does not scale well. A project config lets you define strictness, module behavior, output folders, included files, path aliases, library types, and framework-specific settings in one place.

Basic tsconfig

Basic tsconfig
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "strict": true,
    "moduleResolution": "Bundler",
    "noEmit": true
  },
  "include": ["src"]
}

Creating a Config File

The fastest way to create a starting config is npx tsc --init. It creates a tsconfig.json file with many available options shown as comments or defaults, depending on your TypeScript version.

After generating it, simplify the file to the options your project actually needs. A smaller config is easier for a team to understand.

Command Purpose
npx tsc --init Create a new tsconfig file.
npx tsc Type-check or compile the project using the config.
npx tsc --showConfig Show the final resolved compiler configuration.

Initialize tsconfig

Initialize tsconfig
npx tsc --init
npx tsc --showConfig

Important Compiler Options

Compiler options decide how strict TypeScript should be, which JavaScript features are expected, how modules are resolved, and whether files are emitted. You do not need to memorize every option, but you should understand the ones that appear in most projects.

Option Meaning Typical Use
target JavaScript version to output or type-check against Use modern targets such as ES2020 or ES2022 for current runtimes
module Module format such as ESNext or CommonJS Use ESNext for modern bundlers, CommonJS for older Node setups
strict Turns on the main strict checking options Recommended for new projects
moduleResolution How imports are resolved Bundler for Vite/Next-style apps, NodeNext for modern Node packages
noEmit Check types but do not write JS output Common when a framework or bundler emits code
outDir Folder where compiled files are written Useful for plain Node projects
rootDir Source folder used as output root Often src when output goes to dist
include Files or folders TypeScript should include Keeps the project scope clear

Strict Mode

New projects should usually enable strict. It makes TypeScript much more helpful by preventing implicit any, unsafe null usage, weak assumptions about class properties, and unsafe function assignments.

Strict mode can feel demanding at first, but it teaches better habits quickly. It also catches exactly the kind of bugs that often appear later as undefined values, bad function calls, or incomplete objects.

  • strictNullChecks forces you to handle null and undefined.
  • noImplicitAny prevents accidental untyped parameters.
  • strictFunctionTypes makes function assignment safer.
  • strictPropertyInitialization checks class properties before use.
  • alwaysStrict emits JavaScript in strict mode.

noEmit vs outDir

Use noEmit when TypeScript should only check types and another tool handles output. This is common in Vite, Next.js, React, Vue, and many frontend projects.

Use outDir when TypeScript itself should write JavaScript files. This is common in simple Node.js projects, command-line tools, and backend projects that compile from src to dist.

Setting What Happens
"noEmit": true TypeScript checks code but does not write JavaScript files.
"outDir": "dist" TypeScript writes compiled files into the dist folder.
Both together Usually not useful because noEmit prevents output.

Compiler Emits JavaScript

Compiler Emits JavaScript
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "CommonJS",
    "rootDir": "src",
    "outDir": "dist",
    "strict": true
  },
  "include": ["src"]
}

include, exclude and files

include defines the folders or file patterns TypeScript should load. Most projects include src. exclude removes folders from that set, such as build output or generated files.

files is more exact: it lists specific files one by one. It is rarely needed for normal app projects but can be useful for tiny packages or special build configs.

Project Scope

Project Scope
{
  "compilerOptions": {
    "strict": true,
    "noEmit": true
  },
  "include": ["src/**/*.ts"],
  "exclude": ["dist", "node_modules"]
}

Path Aliases

Path aliases let you replace long relative imports with stable project-based imports. Instead of writing ../../../services/userService, you can write something like @/services/userService.

Aliases must be understood by TypeScript and by the tool that runs or bundles your code. In frontend projects, configure the bundler too. In Node.js projects, make sure runtime resolution supports the alias.

baseUrl and paths

baseUrl and paths
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"],
      "@/components/*": ["src/components/*"]
    }
  }
}

Practical Advice

If a framework creates tsconfig files for you, start with its defaults. Framework templates often include settings required by their build system. Change settings gradually and understand why each change is needed.

For libraries, declaration files may matter because consumers need type information. For apps using Vite or Next.js, noEmit is common because the framework handles bundling. For Node services, compiling from src to dist is still a clear and practical setup.

  • Keep strict enabled for new projects.
  • Use include to keep TypeScript focused on source files.
  • Avoid copying huge configs without understanding the options.
  • Use --showConfig when you need to debug the final resolved settings.
Before you move on

tsconfig.json Explained: Strict TypeScript Project Configuration Mastery Check

5 checks
  • tsconfig.json defines project-wide TypeScript behavior.
  • strict is recommended for new projects because it catches important bugs early.
  • noEmit is common when a bundler handles output; outDir is used when TypeScript emits JavaScript.
  • include and exclude control which files belong to the project.
  • Path aliases improve imports, but the runtime or bundler must also understand them.
Browse Free Tutorials

Explore 500+ free tutorials across 20+ languages and frameworks.