Babel Configuration for JavaScript Transpilation
Babel turns modern JavaScript into code older browsers understand. Additionally it processes JSX, TypeScript (without type checking), experimental TC39 proposals and decorators. In 2025, Babel is increasingly replaced by SWC for transpilation, but remains indispensable for complex AST transformations and custom plugins.
Installation
# Core and CLI
npm install --save-dev @babel/core @babel/cli
# Preset for modern JS
npm install --save-dev @babel/preset-env
# For React
npm install --save-dev @babel/preset-react
# For TypeScript
npm install --save-dev @babel/preset-typescript
# Runtime for async/await without polyfills in each file
npm install --save-dev @babel/plugin-transform-runtime
npm install @babel/runtime
babel.config.json
{
"presets": [
[
"@babel/preset-env",
{
"targets": "> 0.5%, last 2 versions, not dead, not ie 11",
"useBuiltIns": "usage",
"corejs": "3.38",
"modules": false
}
],
[
"@babel/preset-react",
{
"runtime": "automatic"
}
],
[
"@babel/preset-typescript",
{
"allExtensions": true,
"isTSX": true
}
]
],
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"corejs": false,
"helpers": true,
"regenerator": true
}
]
],
"env": {
"test": {
"presets": [
["@babel/preset-env", { "targets": { "node": "current" }, "modules": "commonjs" }]
]
}
}
}
"modules": false in preset-env is important for bundlers — allows bundler (Webpack, Rollup) to handle ESM imports and do tree-shaking. In test environment (Jest) need "modules": "commonjs" because Node.js historically uses CJS.
Targets and browserslist
Instead of explicit specification in Babel config, better use .browserslistrc or browserslist section in package.json — this file is read by Babel, Autoprefixer, and other tools:
# .browserslistrc
[production]
> 0.5%
last 2 versions
not dead
not ie 11
[development]
last 1 chrome version
last 1 firefox version
last 1 safari version
Decorators
TypeScript decorators (metadata, Angular, MobX, TypeORM) require special plugin:
npm install --save-dev @babel/plugin-proposal-decorators
{
"plugins": [
["@babel/plugin-proposal-decorators", { "version": "2023-11" }]
]
}
Version "2023-11" is finalized TC39 Stage 3 standard. For projects with legacy TypeScript decorators (experimentalDecorators: true) use "legacy":
["@babel/plugin-proposal-decorators", { "version": "legacy" }]
Webpack integration
npm install --save-dev babel-loader
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(js|jsx|ts|tsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
cacheDirectory: true, // cache in node_modules/.cache/babel-loader
cacheCompression: false, // without gzip — faster on SSD
},
},
},
],
},
};
Jest integration
npm install --save-dev babel-jest
Jest picks up babel config automatically if project has babel.config.json. Separate setup only needed for specific config:
// jest.config.js
module.exports = {
transform: {
'^.+\\.(js|jsx|ts|tsx)$': ['babel-jest', { configFile: './babel.config.test.json' }],
},
};
Timeline
Basic Babel setup for React/TypeScript project: 1–2 hours. Setup with decorators, custom plugins, core-js polyfills and CI integration: 4–8 hours.







