Hot module replacement transforms for Remix UI components, with integrations for Node and remix/assets.
ui-hmr rewrites supported Remix UI component modules so they can use the standard import.meta.hot APIs provided by packages like assets and node-hmr.
- Stable Components - Keep component identity stable while swapping implementations
- Remount Fallbacks - Mark components stale when their setup scope changes
- Node Module Hooks - Transform server component modules through Node's module customization hooks API
- Assets Loader - Transform component modules for the browser through
remix/assets
npm i remixUse remix/ui-hmr/node as a Node import hook for server modules:
node --import remix/node-tsx --import remix/ui-hmr/node ./server.tsUse uiHmr() from remix/ui-hmr/assets with remix/assets for browser modules:
import { createAssetServer } from 'remix/assets'
import { uiHmr } from 'remix/ui-hmr/assets'
let isDevelopment = process.env.NODE_ENV === 'development'
let assetServer = createAssetServer({
basePath: '/assets',
fileMap: { '/app/*path': 'app/*path' },
allowFiles: ['app/**'],
hmr: isDevelopment
? async () => (await import('remix/node-hmr/runtime')).createBrowserHmrChannel()
: undefined,
scripts: {
loaders: isDevelopment ? [uiHmr()] : undefined,
},
watch: isDevelopment,
})Use the direct transform APIs when you are writing your own loader, Node module hooks, or build integration.
import { transformComponentsForBrowser } from 'remix/ui-hmr'
let result = transformComponentsForBrowser(source, {
importSource: 'remix',
moduleUrl: '/assets/app/routes.tsx',
})
if (result.transformed) {
console.log(result.componentNames)
}transformComponentsForBrowser(source, options) rewrites browser component modules and emits import.meta.hot.accept() code for browser updates. The direct transform uses importSource to derive imports for the UI refresh runtime and browser HMR runtime.
import { transformComponentsForServer } from 'remix/ui-hmr'
let result = transformComponentsForServer(source, {
importSource: 'remix',
moduleUrl: 'file:///app/routes.tsx',
})transformComponentsForServer(source, options) rewrites server component modules and registers updated component implementations for the current module URL. The direct transform uses importSource to derive imports for the server HMR runtime.
Both transforms return:
type ComponentsHmrTransformResult = {
code: string
componentNames: string[]
map: string | null
transformed: boolean
}Pass sourceMap: true to generate a source map.
Use importSource to define where injected imports come from, typically either remix or @remix-run:
transformComponentsForBrowser(source, {
importSource: 'remix',
moduleUrl: '/assets/app/routes.tsx',
})
transformComponentsForServer(source, {
importSource: 'remix',
moduleUrl: 'file:///app/routes.tsx',
})importSource: 'remix' generates imports from remix/ui and remix/ui-hmr. importSource: '@remix-run' generates imports from @remix-run/ui and @remix-run/ui-hmr. Custom import sources follow the same nested import layout.
assets- Runs loaders while compiling assetsnode-hmr- Provides the server-sideimport.meta.hotruntimeui- Component APIs transformed byui-hmr
See LICENSE