patternjavascriptTip
unbuild: stub mode for instant monorepo DX without rebuilding
Viewed 0 times
unbuild 2+
unbuild stubmonorepo dxlibrary watchinstant rebuildjiti proxy
Problem
Developing a library inside a monorepo requires rebuilding the package after every change before the consuming app sees updated code, adding a slow feedback loop.
Solution
Use unbuild's stub mode to generate a thin ESM proxy that re-exports source files directly — no build step needed during development.
# package.json scripts
{
"scripts": {
"build": "unbuild",
"stub": "unbuild --stub"
}
}
# build.config.ts
import { defineBuildConfig } from 'unbuild';
export default defineBuildConfig({
entries: ['src/index'],
rollup: { emitCJS: true },
declaration: true,
});
# Run stub once to set up the proxy
pnpm stub
# Now changes to src/ are immediately reflected in consumers
# without re-running any build
# package.json scripts
{
"scripts": {
"build": "unbuild",
"stub": "unbuild --stub"
}
}
# build.config.ts
import { defineBuildConfig } from 'unbuild';
export default defineBuildConfig({
entries: ['src/index'],
rollup: { emitCJS: true },
declaration: true,
});
# Run stub once to set up the proxy
pnpm stub
# Now changes to src/ are immediately reflected in consumers
# without re-running any build
Why
The stub output is a tiny file that re-exports from the source via Node's 'exports' field. Since Node follows the chain, the consumer always reads the latest source. This is the workflow used by Nuxt's own packages.
Gotchas
- Stub mode only works for ESM consumers that respect the 'exports' field
- Run 'unbuild' (not --stub) before publishing to produce actual compiled output
- TypeScript type checking still requires tsc — stub mode skips compilation entirely
- Not all runtime environments support 'exports' field resolution (older Jest configs may not)
Context
Developing a library package inside a monorepo without a watch/rebuild loop
Revisions (0)
No revisions yet.