Understand the Next.js SWC compiler, build options, and performance optimizations.
# No configuration needed - works out of the box
npm run buildnpm run build
# Unused imports and exports are removed automaticallynext info
# Shows SWC or Babel depending on your config// next.config.js
module.exports = {
compiler: {
reactRemoveProperties: true, // Remove React debugging props
removeConsole: {
exclude: ['error', 'warn'] // Keep error and warn logs
}
}
};module.exports = {
compiler: { styledComponents: true }
};module.exports = {
compiler: {
removeConsole: { exclude: ['error', 'warn'] }
}
};module.exports = {
compiler: {
reactRemoveProperties: { properties: ["^data-testid$"] }
}
};module.exports = {
compiler: { emotion: true }
};optimizePackageImports.// next.config.js
module.exports = {
experimental: {
optimizePackageImports: ["lucide-react", "@heroicons/react", "@mui/material"]
}
};output: 'standalone' for minimal Docker images in production.module.exports = {
output: "standalone" // Creates .next/standalone with no node_modules needed
};next dev --turbopack
# Rust-based bundler: faster incremental builds than webpack.babelrc to re-enable SWC if your project accidentally falls back to Babel.# Next.js uses Babel instead of SWC when .babelrc exists
rm .babelrc # or migrate its config to next.config.js compiler optionsnpm install -D @next/bundle-analyzer
ANALYZE=true npm run build # Opens interactive treemapimport { Inter } from 'next/font/google';
const inter = Inter();"use server";
export async function save(data: FormData) {
// Compiled to a secure server endpoint automatically
}{
"compilerOptions": {
"paths": { "@/*": ["./src/*"] }
}
}npm run build to catch First Load JS regressions.npm run build
# Route Size First Load JS
# / 5.2 kB 89.3 kB ← aim for < 130 kBconst withBundleAnalyzer = require("@next/bundle-analyzer")({
enabled: process.env.ANALYZE === "true"
});
module.exports = withBundleAnalyzer({});- name: Lighthouse CI
run: lhci autorun
env:
LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_TOKEN }}{
"assert": {
"assertions": {
"categories:performance": ["error", { "minScore": 0.9 }]
}
}
}next info in the terminal to confirm whether SWC or Babel is active.next info
# Operating System: ..., SWC: trueSWC can be up to 17x faster for local compilation and 5x faster for full production builds. The difference is most noticeable in large projects with hundreds of files, where Babel's JavaScript-based transforms become the bottleneck.
Add a compiler key in next.config.js — for example, compiler: { styledComponents: true } enables the styled-components transform natively via SWC. This replaces the need for babel-plugin-styled-components and works automatically in both dev and production.
Next.js automatically falls back to Babel when it detects a .babelrc or babel.config.js file in the project root. Delete these files (migrating any custom plugins to next.config.js compiler options) to re-enable SWC.
Use modularizeImports in next.config.js to rewrite bulk imports into per-file imports at compile time — for example, configuring it for @mui/icons-material prevents the entire icon library from being bundled. This is handled by the SWC compiler and requires no runtime code changes.
Install @next/bundle-analyzer and set ANALYZE=true next build to get an interactive treemap of your bundles. For raw build timing, the CLI output already reports per-page sizes and the First Load JS for each route after every build.