Skip to main content

Overview

ts-loader is a TypeScript loader for webpack that compiles TypeScript files (.ts and .tsx) to JavaScript. It uses the official TypeScript compiler and provides full type checking during the webpack build process.
This is an external loader maintained by the TypeScript community. Install it from npm to use in your webpack configuration.

Installation

npm install -D ts-loader typescript

Basic Usage

module.exports = {
  entry: './src/index.ts',
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/
      }
    ]
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.js']
  }
};

Options

configFile

Specify a custom TypeScript config file:
{
  loader: 'ts-loader',
  options: {
    configFile: path.resolve(__dirname, 'tsconfig.build.json')
  }
}

transpileOnly

Disable type checking for faster builds:
{
  loader: 'ts-loader',
  options: {
    transpileOnly: true
  }
}
transpileOnly: true skips type checking. Use fork-ts-checker-webpack-plugin to run type checking in a separate process.

compilerOptions

Override tsconfig.json options:
{
  loader: 'ts-loader',
  options: {
    compilerOptions: {
      target: 'es6',
      module: 'esnext'
    }
  }
}

happyPackMode

Enable for use with thread-loader or HappyPack:
{
  loader: 'ts-loader',
  options: {
    happyPackMode: true
  }
}

React/JSX Support

module.exports = {
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/
      }
    ]
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.js']
  }
};

Performance Optimization

Fork TS Checker Plugin

Run type checking in a separate process:
npm install -D fork-ts-checker-webpack-plugin
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');

module.exports = {
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: {
          loader: 'ts-loader',
          options: {
            transpileOnly: true
          }
        },
        exclude: /node_modules/
      }
    ]
  },
  plugins: [
    new ForkTsCheckerWebpackPlugin()
  ]
};
This significantly improves build speed by running type checking in parallel with transpilation.

Thread Loader

Run ts-loader in parallel:
npm install -D thread-loader
{
  test: /\.tsx?$/,
  use: [
    'thread-loader',
    {
      loader: 'ts-loader',
      options: {
        happyPackMode: true
      }
    }
  ],
  exclude: /node_modules/
}

Cache

Webpack 5 has built-in caching:
module.exports = {
  cache: {
    type: 'filesystem'
  },
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/
      }
    ]
  }
};

Common Patterns

Development vs Production

const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');

module.exports = {
  mode: 'development',
  devtool: 'inline-source-map',
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: {
          loader: 'ts-loader',
          options: {
            transpileOnly: true
          }
        },
        exclude: /node_modules/
      }
    ]
  },
  plugins: [
    new ForkTsCheckerWebpackPlugin()
  ]
};

Monorepo Setup

{
  test: /\.tsx?$/,
  use: {
    loader: 'ts-loader',
    options: {
      projectReferences: true
    }
  },
  exclude: /node_modules/
}
tsconfig.json
{
  "compilerOptions": {
    "composite": true,
    "declaration": true
  },
  "references": [
    { "path": "../shared" },
    { "path": "../utils" }
  ]
}

Path Mapping

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

TypeScript Configuration

Strict Mode

{
  "compilerOptions": {
    "strict": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "strictBindCallApply": true,
    "strictPropertyInitialization": true,
    "noImplicitThis": true,
    "alwaysStrict": true
  }
}

Module Resolution

{
  "compilerOptions": {
    "moduleResolution": "node",
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "resolveJsonModule": true
  }
}

Output Options

{
  "compilerOptions": {
    "target": "es2020",
    "module": "esnext",
    "lib": ["es2020", "dom"],
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true
  }
}

Alternative: babel-loader

For faster builds without type checking:
npm install -D @babel/preset-typescript
Babel does not perform type checking. Use tsc --noEmit or fork-ts-checker-webpack-plugin for type checking.

Common Issues

Issue: Slow Build Times

Solution: Use transpileOnly with fork-ts-checker-webpack-plugin:
{
  loader: 'ts-loader',
  options: {
    transpileOnly: true
  }
}

Issue: Cannot Find Module

Solution: Add file extensions to resolve.extensions:
resolve: {
  extensions: ['.tsx', '.ts', '.js', '.json']
}

Issue: Type Errors Not Shown

Solution: Ensure type checking is enabled:
// Remove transpileOnly or add fork-ts-checker-webpack-plugin
{
  loader: 'ts-loader'
  // options: { transpileOnly: true } // Remove this
}

Issue: Path Aliases Not Working

Solution: Configure both tsconfig.json and webpack:
tsconfig.json
{
  "compilerOptions": {
    "paths": {
      "@/*": ["src/*"]
    }
  }
}
webpack.config.js
resolve: {
  alias: {
    '@': path.resolve(__dirname, 'src')
  }
}

ts-loader vs babel-loader

Featurets-loaderbabel-loader
Type CheckingYes (optional)No
PerformanceSlowerFaster
TypeScript FeaturesFull supportLimited
Setup ComplexitySimpleMore config
Best ForType safetySpeed

Complete Example

webpack.config.js
const path = require('path');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');

module.exports = {
  mode: 'development',
  entry: './src/index.ts',
  devtool: 'inline-source-map',
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: {
          loader: 'ts-loader',
          options: {
            transpileOnly: true,
            configFile: path.resolve(__dirname, 'tsconfig.json')
          }
        },
        exclude: /node_modules/
      }
    ]
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.js'],
    alias: {
      '@': path.resolve(__dirname, 'src')
    }
  },
  plugins: [
    new ForkTsCheckerWebpackPlugin({
      async: true,
      typescript: {
        configFile: path.resolve(__dirname, 'tsconfig.json')
      }
    })
  ],
  cache: {
    type: 'filesystem'
  }
};

Resources