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
webpack.config.js
tsconfig.json
src/index.ts
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
webpack.config.js
tsconfig.json
component.tsx
module . exports = {
module: {
rules: [
{
test: / \. tsx ? $ / ,
use: 'ts-loader' ,
exclude: /node_modules/
}
]
},
resolve: {
extensions: [ '.tsx' , '.ts' , '.js' ]
}
};
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/
}
{
"compilerOptions" : {
"composite" : true ,
"declaration" : true
},
"references" : [
{ "path" : "../shared" },
{ "path" : "../utils" }
]
}
Path Mapping
tsconfig.json
webpack.config.js
{
"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:
Installation
webpack.config.js
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:
{
"compilerOptions" : {
"paths" : {
"@/*" : [ "src/*" ]
}
}
}
resolve : {
alias : {
'@' : path . resolve ( __dirname , 'src' )
}
}
ts-loader vs babel-loader
Feature ts-loader babel-loader Type Checking Yes (optional) No Performance Slower Faster TypeScript Features Full support Limited Setup Complexity Simple More config Best For Type safety Speed
Complete Example
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