nextjs - 💡(How to fix) Fix Turbopack: mixing direct and barrel imports of the same module causes undefined component at runtime [1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
vercel/next.js#91926Fetched 2026-04-08 01:30:03
View on GitHub
Comments
1
Participants
2
Timeline
4
Reactions
0
Author
Timeline (top)
closed ×1commented ×1labeled ×1locked ×1

Error Message

Current: Overline is undefined at runtime → React error #130 (Element type is invalid: expected a string or class/function but got: undefined).

Root Cause

We've hit this same class of bug multiple times in our monorepo. A previous instance (different component, same root cause) was fixed by extracting the component from a barrel to break the conflicting module paths. The pattern seems to be: when Turbopack's barrel optimization is active and both direct and barrel import paths coexist for the same underlying module, the direct path's chunk dependencies aren't correctly tracked.

Fix Action

Workaround

Change the direct import to use the barrel:

-import { Text } from '@my-org/ui-lib/typography';
-import Overline from '@my-org/ui-lib/typography/Overline';
+import { Overline, Text } from '@my-org/ui-lib/typography';

Code Example

// @my-org/ui-lib/package.json exports
{
  "./typography": "./typography/index.tsx",
  "./typography/Overline": "./typography/Overline.tsx",
  "./typography/Text": "./typography/Text.tsx"
}

---

// @my-org/ui-lib/typography/index.tsx (barrel)
export { default as Heading } from './Heading';
export { default as Overline } from './Overline';
export { default as Text } from './Text';

---

// @my-org/ui-lib/typography/Overline.tsx
import styled from 'styled-components';
export default styled.span`...`;

---

// app/components/RoundsList.tsx
import { Text } from '@my-org/ui-lib/typography';           // barrel
import Overline from '@my-org/ui-lib/typography/Overline';   // direct

export const RoundsList = () => (
  <div>
    <Overline>label</Overline>   {/* <-- crashes: Overline is undefined */}
    <Text>value</Text>           {/* works fine */}
  </div>
);

---

-import { Text } from '@my-org/ui-lib/typography';
-import Overline from '@my-org/ui-lib/typography/Overline';
+import { Overline, Text } from '@my-org/ui-lib/typography';
RAW_BUFFERClick to expand / collapse

Link to the code that reproduces this issue

Internal monorepo — minimal reproduction described below.

To Reproduce

Setup: pnpm monorepo, Next.js (Pages Router) with Turbopack enabled.

A UI library package (@my-org/ui-lib) has a typography barrel file and direct sub-path exports:

// @my-org/ui-lib/package.json exports
{
  "./typography": "./typography/index.tsx",
  "./typography/Overline": "./typography/Overline.tsx",
  "./typography/Text": "./typography/Text.tsx"
}
// @my-org/ui-lib/typography/index.tsx (barrel)
export { default as Heading } from './Heading';
export { default as Overline } from './Overline';
export { default as Text } from './Text';
// @my-org/ui-lib/typography/Overline.tsx
import styled from 'styled-components';
export default styled.span`...`;

Consumer component mixes import styles for components from the same barrel:

// app/components/RoundsList.tsx
import { Text } from '@my-org/ui-lib/typography';           // barrel
import Overline from '@my-org/ui-lib/typography/Overline';   // direct

export const RoundsList = () => (
  <div>
    <Overline>label</Overline>   {/* <-- crashes: Overline is undefined */}
    <Text>value</Text>           {/* works fine */}
  </div>
);

This component is rendered lazily (inside an accordion that conditionally renders children with {isOpen && <RoundsList />}).

Other files in the same route import Overline via the barrel (import { Overline } from '@my-org/ui-lib/typography') and work fine — ~10 usages across the chunk, all through the barrel path.

Current vs. Expected behavior

Current: Overline is undefined at runtime → React error #130 (Element type is invalid: expected a string or class/function but got: undefined).

Expected: Both import styles should resolve to the same component.

Analysis from production chunks

Turbopack's barrel optimization creates separate module entries:

  • Module 434297 (barrel-optimized): var o = e.i(663281); e.s(["Overline", () => o.default]) — used 10 times in the chunk, works.
  • Module 663281 (direct import): defines the actual styled component with e.s(["default", 0, o], 663281) — used 1 time (in the broken component), resolves to undefined.

Module 663281 is defined in a different chunk than the consuming component. The barrel-optimized module 434297 has proper chunk dependency declarations, but the direct import path does not — so when the component lazily renders, module 663281's chunk hasn't loaded yet and .default is undefined.

Workaround

Change the direct import to use the barrel:

-import { Text } from '@my-org/ui-lib/typography';
-import Overline from '@my-org/ui-lib/typography/Overline';
+import { Overline, Text } from '@my-org/ui-lib/typography';

Environment

  • Next.js: 15.x (Pages Router)
  • Turbopack enabled (next dev --turbopack and production builds)
  • pnpm monorepo with package.json exports map providing both barrel and direct sub-paths

Which area(s) are affected?

Turbopack

Which stage(s) are affected?

  • next dev (Turbopack)
  • next build (Turbopack)

Additional context

We've hit this same class of bug multiple times in our monorepo. A previous instance (different component, same root cause) was fixed by extracting the component from a barrel to break the conflicting module paths. The pattern seems to be: when Turbopack's barrel optimization is active and both direct and barrel import paths coexist for the same underlying module, the direct path's chunk dependencies aren't correctly tracked.

extent analysis

Fix Plan

To resolve the issue, we need to ensure that the direct import path has the correct chunk dependency declarations.

  • Change the direct import to use the barrel, as shown in the provided workaround:
    -import { Text } from '@my-org/ui-lib/typography';
    -import Overline from '@my-org/ui-lib/typography/Overline';
    +import { Overline, Text } from '@my-org/ui-lib/typography';
  • Alternatively, if you cannot change the import style, you can try to disable Turbopack's barrel optimization for the specific module by adding a // @turbopack(skip-barrel-optimization) comment at the top of the index.tsx file:
    // @turbopack(skip-barrel-optimization)
    export { default as Heading } from './Heading';
    export { default as Overline } from './Overline';
    export { default as Text } from './Text';
  • If the issue persists, consider extracting the component from the barrel to break the conflicting module paths, as done in the previous instance.

Verification

To verify that the fix worked:

  1. Run next dev --turbopack and check if the component renders correctly.
  2. Build the production bundle using next build --turbopack and verify that the issue is resolved.

Extra Tips

To prevent similar issues in the future:

  • Avoid mixing import styles for components from the same barrel.
  • Consider disabling Turbopack's barrel optimization for modules with conflicting import paths.
  • Keep an eye on the chunk dependency declarations and ensure they are correct for all import paths.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING