HMR & Fast Refresh

Dev-only oxc-transform jsx refresh flag Router componentCache clearing import.meta.hot shim.

HMR & Fast Refresh

Development transforms run through oxcPlugin(isDev) (packages/manic/src/cli/plugins/oxc.ts). When isDev is true:

SettingBehavior
jsx.developmenttrue — React dev warnings + richer stacks
jsx.refreshtrue unless config.oxc.refresh === false — enables Fast Refresh pipeline
sourcemapEmitted for transformed modules

Production Bun.build calls oxcPlugin() with isDev falsytarget: es2022, no refresh metadata.


Fast Refresh shim

After transformSync, oxc.ts appends an import.meta.hot.accept stub for .tsx / .jsx files:

if (import.meta.hot) {
  import.meta.hot.accept(() => {
    window.__react_refresh_library__?.performRefresh?.();
  });
}

That wires Bun’s module graph updates into React’s refresh runtime while Router clears route caches.


Router cache invalidation

packages/manic/src/router/lib/Router.tsx keeps a componentCache (Map<string, ComponentType>). On HMR:

if (import.meta.hot) {
  import.meta.hot.accept(() => {
    componentCache.clear();
  });
}

Without clearing, navigations could keep stale lazy components after a hot swap.


Config knob

Disable refresh-driven behavior globally via manic.config.ts:

export default defineConfig({
  oxc: { refresh: false },
});

Disabling server.hmr in config affects Bun.serve development options from createManicServer — pair with CLI manic dev docs.


See also

On this page