August 29, 2025
Barrel files simplify imports by consolidating multiple module exports into a single index file. A common example looks like this:
// utils/index.js
export { default as module1 } from './module1';
export { default as module2 } from './module2';
export { default as module3 } from './module3';
This enables shorter and cleaner import statements:
import { module1, module2, module3 } from './utils';
While barrel files enhance readability, they can significantly increase your bundle size. Bundlers often import the entire barrel file, including unused modules, preventing effective tree shaking.
Tree shaking reduces JavaScript bundle sizes by removing unused code. However, barrel files obscure direct import-module relationships, causing unnecessary code retention and inflated bundles, negatively impacting your app’s performance.
Identifying barrel files is essential but can be challenging, often requiring manual effort. Inspect your bundle visually for unusually large files or systematically review your index.js and index.ts files.
Removing barrel files is essential for Next.js versions below 13.1 or for barrel files in your own codebase. For instance, one of our clients reduced their bundle size by 400 KB simply by removing a barrel file exporting multiple SVGs, originally adding 477 KB.
For TypeScript projects, maintain convenience using tsconfig.json paths:
// tsconfig.json
"baseUrl": ".",
"paths": {
"@/utils/*": ["./utils/*"],
}
},
Results in clear imports:
import { module1, module2, module3 } from '@/utils';
Modularized imports rewrite import statements to enable tree shaking:
// Before (with barrel file)
import { Button, Slider, Dropdown } from '@acme/ui';
// After (with modularized imports from plugin)
import Button from '@acme/ui/dist/Button';
import Slider from '@acme/ui/dist/Slider';
import Dropdown from '@acme/ui/dist/Dropdown';
Download our service guide to understand how we can help you optimise your site speed
Configure modularized imports in your next.config.js:
// next.config.js
module.exports = {
modularizeImports: {
'@acme/ui': {
transform: '@acme/ui/dist/{{member}}',
},
},
};
This approach clearly maps imports, bypassing barrel files, but has limitations: extensive manual configuration can be cumbersome for large-scale applications or projects with many dependencies, and it only supports third-party libraries.
From Next.js 13.5 onwards, automatic import optimization is available:
// next.config.js
module.exports = {
experimental: {
optimizePackageImports: [
'@phosphor-icons/react',
'@radix-ui/react-icons',
'validator',
'@mantine/core',
],
},
};
When enabled, Next.js analyzes entry barrel files and automatically maps all imports, similar to modularize imports.
Next.js automatically includes some libraries by default; see Next.js default optimization list.
You can read more about these options in our When to Use optimizePackageImports vs modularizeImports - and the Gotchas post!
Optimizing your bundle size improves performance, enhances user experience, and boosts ad revenue. Follow these strategies in your Next.js projects to keep your apps fast and user-friendly.
Our experts in Next.js performance can help you improve the speed and performance of your app.Get in touchto learn how we can help.
Download our service guide to understand how
we can help you optimise your site speed