Related plugins
Description
When exporting components as a compound object (e.g. export const Accordion = { Root, Item }), React Fast Refresh treats the module as “impure” and falls back to a full reload instead of hot‐swapping the individual subcomponents.
// src/Accordion.tsx
import React from 'react'
const Root: React.FC = () => <div>Accordion Root</div>
const Item: React.FC = () => <div>Accordion Item</div>
export const Accordion = { Root, Item }
// → Editing `Root` or `Item` causes a full reload rather than HMR
Suggested solution
Modify the Fast Refresh logic so that any top‐level export const X = { A, B, … } is inspected. If all properties (A, B, …) refer to PascalCase functions or classes defined in the same file (i.e. valid React components), treat them as HMR boundaries instead of marking the module as impure.
Alternative
-
Barrel export in the same package
// src/components/accordion/components.tsx
import React from 'react'
export const Root: React.FC = () => <div>Accordion Root</div>
export const Item: React.FC = () => <div>Accordion Item</div>
// src/components/accordion/index.ts
export * as Accordion from './components'
- Trade-off: Explicitly re‐exports
Root and Item to enable HMR, but adds extra named exports that clutter IntelliSense.
- Separate “micro” package for subcomponents
// packages/accordion/src/components.tsx
import React from 'react'
export const Root: React.FC = () => <div>Accordion Root</div>
export const Item: React.FC = () => <div>Accordion Item</div>
// packages/accordion/src/index.tsx
export * as Accordion from './components'
// apps/app/src/index.tsx
import { Accordion } from "@org/accordion"
return (
<Accordion.Root>
<Accordion.Item>...</Accordion.Item>
</Accordion.Root>
)
- Trade-off: While intellisense won't suggested slot components anymore, micro-frontends are not for everyone and they introduce an additional complexity
Additional context
Compound components (e.g. <Accordion.Root>, <Accordion.Item>) are a common pattern in UI libraries. Being forced to do a full page reload instead of hot‐swapping slows down development. Enabling HMR for a single object export when all children are valid React components would significantly improve developer experience.
Validations
Related plugins
plugin-react
plugin-react-swc
plugin-react-oxc
Description
When exporting components as a compound object (e.g.
export const Accordion = { Root, Item }), React Fast Refresh treats the module as “impure” and falls back to a full reload instead of hot‐swapping the individual subcomponents.Suggested solution
Modify the Fast Refresh logic so that any top‐level
export const X = { A, B, … }is inspected. If all properties (A,B, …) refer to PascalCase functions or classes defined in the same file (i.e. valid React components), treat them as HMR boundaries instead of marking the module as impure.Alternative
Barrel export in the same package
RootandItemto enable HMR, but adds extra named exports that clutter IntelliSense.Additional context
Compound components (e.g.
<Accordion.Root>,<Accordion.Item>) are a common pattern in UI libraries. Being forced to do a full page reload instead of hot‐swapping slows down development. Enabling HMR for a single object export when all children are valid React components would significantly improve developer experience.Validations