JavaScript Transpiler Configuration
💡 Quick Start: For a concise guide to migrating from Babel to SWC, see Common Upgrades Guide - Babel to SWC.
Default Transpilers
Shakapacker v10 transpiler defaults depend on the bundler and installation:
- New installations (v9+, including v10):
swc- Installation template explicitly sets SWC, which upstream reports as 20x faster than Babel single-threaded and 70x on four cores - Webpack runtime default:
babel- Used when no explicit config is provided (maintains backward compatibility) - Rspack runtime default:
swc- Rspack defaults to SWC as it's a newer bundler with modern defaults
Key distinction: The installation template (lib/install/config/shakapacker.yml) explicitly sets javascript_transpiler: "swc" for new projects, but if you're upgrading or have no explicit config, webpack falls back to Babel for backward compatibility.
Available Transpilers
babel- Traditional JavaScript transpiler with wide ecosystem supportswc- High-performance Rust-based transpiler; upstream reports 20x faster than Babel single-threaded and 70x on four coresesbuild- Go-based transpiler; extremely fast for supported transforms (benchmark)none- No transpilation (use native JavaScript)
Configuration
Set the transpiler in your config/shakapacker.yml:
default: &default # Choose one transpiler:
javascript_transpiler: swc # default, recommended
# javascript_transpiler: babel
# javascript_transpiler: esbuild
# assets_bundler: webpack # default; for rspack, set: assets_bundler: rspack
Migration Guide
Migrating from Babel to SWC
SWC offers significant performance improvements while maintaining high compatibility with Babel.
1. Install SWC dependencies
yarn add --dev @swc/core swc-loader
2. Update your configuration
# config/shakapacker.yml
default: &default
javascript_transpiler: swc
3. Create SWC configuration (optional)
If you need custom transpilation settings, create config/swc.config.js:
// config/swc.config.js
// This file is merged with Shakapacker's default SWC configuration
// See: https://swc.rs/docs/configuration/compilation
module.exports = {
options: {
jsc: {
transform: {
react: {
runtime: "automatic"
}
}
}
}
}
Important: Use config/swc.config.js instead of .swcrc. The .swcrc file completely overrides Shakapacker's default SWC settings and can cause build failures. config/swc.config.js properly merges with Shakapacker's defaults.
4. Update React configuration (if using React)
For React projects, ensure you have the correct refresh plugin:
# For webpack
yarn add --dev @pmmmwh/react-refresh-webpack-plugin
# For rspack
yarn add --dev @rspack/plugin-react-refresh
Performance Expectations
SWC's own benchmark reports being 20x faster than Babel single-threaded and 70x faster on four cores for pure transpilation. Transpilation is usually the dominant cost in Babel-heavy Shakapacker builds, so this translates into a large end-to-end win for most apps, even though the full Shakapacker pipeline (CSS, minification, source maps, plugins) means the end-to-end speedup is usually smaller than the pure-transpiler number.
Confirm the gain on your codebase by following Measuring Your App before and after the migration.
Compatibility Notes
Babel Features Not Yet in SWC
- Some experimental/stage-0 proposals
- Custom Babel plugins (need SWC equivalents)
- Babel macros
Migration Checklist
- Back up your current configuration
- Install SWC dependencies
- Update
shakapacker.yml - If using Stimulus, ensure
keepClassNames: trueis set inconfig/swc.config.js(automatically included in v9.1.0+, including v10) - Test your build locally
- Run your test suite
- Check browser compatibility
- Deploy to staging environment
- Monitor for any runtime issues
Stimulus Compatibility
If you're using Stimulus, you must configure SWC to preserve class names. See the Using SWC with Stimulus section for detailed instructions.
Quick summary: Add keepClassNames: true to your config/swc.config.js:
module.exports = {
options: {
jsc: {
keepClassNames: true // Required for Stimulus
}
}
}
Starting with Shakapacker v9.1.0 (and continuing in v10), running rake shakapacker:migrate_to_swc automatically creates a configuration with this setting.
Rollback Plan
If you encounter issues, rolling back is simple:
# config/shakapacker.yml
default: &default
javascript_transpiler: babel # Revert to babel
Then rebuild your application:
bundle exec rake shakapacker:clobber
bundle exec rake shakapacker:compile
Environment Variables
You can also control the transpiler via environment variables:
# Override config file setting
SHAKAPACKER_JAVASCRIPT_TRANSPILER=swc bundle exec rake shakapacker:compile
# For debugging
SHAKAPACKER_DEBUG_CACHE=true bundle exec rake shakapacker:compile
Troubleshooting
Issue: Build fails after switching to SWC
Solution: Ensure all SWC dependencies are installed:
yarn add --dev @swc/core swc-loader
Issue: React Fast Refresh not working
Solution: Install the correct refresh plugin for your bundler:
# Webpack
yarn add --dev @pmmmwh/react-refresh-webpack-plugin
# Rspack
yarn add --dev @rspack/plugin-react-refresh
Issue: Decorators not working
Solution: Enable decorator support in config/swc.config.js:
// config/swc.config.js
module.exports = {
options: {
jsc: {
parser: {
decorators: true,
decoratorsBeforeExport: true
}
}
}
}