Run next build on a project that uses @mui/material and, on some Next.js
versions, the terminal fills with warnings shaped like this:
The requested module '__barrel_optimize__?names=useTheme&wildcard!=!./styles'
contains conflicting star exports for the name '__esModule' with the previous
requested module '__barrel_optimize__?names=useTheme&wildcard!=!./utils'
Should you care? Usually not. The build completes, the output works, and the
warning is noise from Next.js rewriting your MUI imports behind the scenes — the
pattern reported in vercel/next.js #55663
built and ran fine. But "usually" is doing some work in that sentence: the same
machinery has shipped versions where the optimisation silently stopped working
and the whole of @mui/material landed in the client bundle. So the right move
is to understand what the warning is, check your bundle once, and then silence
it deliberately.
The mechanism: barrel files and what Next.js does to them
@mui/material's root index.js is a barrel file — a module whose only job
is to re-export hundreds of others so you can write:
import { Box, Button, useTheme } from '@mui/material';
Convenient, but expensive. Resolving that one import means resolving everything
the barrel re-exports, which slows both next dev and next build, and — with
bundlers that cannot fully tree-shake the package — can drag unused components
into your bundle.
Next.js addresses this with
optimizePackageImports:
at build time it rewrites the barrel import into direct per-module imports, "only
load[ing] the modules you are actually using, while still giving you the
convenience of writing import statements with many named exports". The docs list
the packages optimised by default — @mui/material and @mui/icons-material
are both on it, alongside lucide-react, date-fns, antd and others. The
feature still sits under the experimental key.
The __barrel_optimize__?names=... string in the warning is that rewrite made
visible: it is the internal loader Next.js generates for each barrel it
transforms. The "conflicting star exports for __esModule" complaint happens
when two rewritten modules both re-export the same synthetic __esModule
marker — an artefact of how MUI structures its wildcard exports, not of your
code. The warnings arrived with the barrel optimiser itself in Next.js 13.5
(issue #55663 was filed against 13.5.2-canary.1 and later closed).
Silence it properly — options from cleanest to bluntest
1. Import from the component path directly
MUI's own
bundle-size guidance
recommends first-level path imports:
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import { useTheme } from '@mui/material/styles';
No barrel, nothing to rewrite, no warning — and the fastest dev-server resolve
times of any option. The cost is more import lines, which your editor's
auto-import handles anyway. This is the option we use in the patterns shown in
our Next.js performance guide.
2. Pin the optimiser's behaviour explicitly
If you prefer keeping named imports, declare the package yourself instead of
relying on the default list — explicit config survives default-list changes
between versions:
// next.config.js
module.exports = {
experimental: {
optimizePackageImports: ['@mui/material', '@mui/icons-material'],
},
};
The warnings may remain on affected versions, but the rewrite is guaranteed on,
which is what actually matters for your bundle.
3. Upgrade Next.js
The noisy-warning phase clusters around Next.js 13.5–14.x. The original issue is
closed, and current majors do not emit the __esModule conflict for standard
@mui/material imports. If you are stuck on an affected version for other
reasons, treat the warning as cosmetic — after the one check below.
When the warning is hiding a real problem
Two failure modes reported against the same machinery deserve a check rather
than a shrug:
-
The optimisation silently off. Issue #57624
reported that on early Next.js 14 releases
optimizePackageImportsstopped working and the entire@mui/materialpackage shipped to the client despite being on the default list. Warnings absent ≠ bundle healthy. -
Turbopack gaps. Issue #75131
(January 2025) reported barrel optimisation not applying to
@mui/joyunder--turbopack, and #75148 the same for local workspace packages. If you build with Turbopack, do not assume parity with the webpack path — the two bundlers resolve differently, as we saw from the other side in the Turbopack stuck-build investigation.
The check is one command:
ANALYZE=true next build # with @next/bundle-analyzer wired in next.config.js
Open the client-bundle report and look for @mui/material as a single large
block. Seeing individual small modules (Box, Button, …) means the rewrite
works and the warnings are cosmetic. Seeing the whole package means you are in
the #57624 case: switch to direct path imports (option 1), which fixes the
bundle regardless of what the optimiser does.
Upstream status
As of our last check (August 2026): #55663 is closed; the
optimizePackageImports API remains documented as experimental with
@mui/material on the default list; the Turbopack-specific gaps (#75131,
75148) were filed in 2025 against the newer bundler path. If your exact
warning text differs from the __esModule conflict above, search it verbatim in
the vercel/next.js issue tracker —
the barrel optimiser produces several distinct messages, and build errors that
merely mention a module path can have unrelated causes, as with
the next/babel parsing error
or ChunkLoadError failures at runtime.
Originally published at https://www.iloveblogs.blog
Top comments (0)