Interface: WatchOptions
Extends
Properties
checks?
- Type:
optionalchecks:ChecksOptions
Controls which warnings are emitted during the build process. Each option can be set to true (emit warning) or false (suppress warning).
Inherited from
context?
- Type:
optionalcontext:string
The value of this at the top level of each output chunk. For IIFE and UMD formats, this defaults to 'window' or 'global' depending on the platform.
Example
Set custom context
export default {
context: 'globalThis',
output: {
format: 'iife',
},
};Use window for browser builds
export default {
context: 'window',
platform: 'browser',
output: {
format: 'iife',
},
};In-depth
The context option controls what this refers to in the top-level scope of your bundled code. This is particularly important for:
- IIFE bundles that need to access global objects
- UMD bundles that run in multiple environments
- Code that references
thisat the top level
By default:
- For
'iife'and'umd'formats on browser platform:thisis'window' - For
'iife'and'umd'formats on node platform:thisis'global' - For ES modules:
thisisundefined
Using 'globalThis' provides a cross-platform way to access the global object that works in both browser and Node.js environments.
Inherited from
cwd?
- Type:
optionalcwd:string
The working directory to use when resolving relative paths in the configuration.
Default
process.cwd()Inherited from
devtools?
- Type:
optionaldevtools:object
sessionId?
- Type:
optionalsessionId:string
Inherited from
experimental?
- Type:
optionalexperimental:object
Experimental features that may change in future releases and can introduce behavior change without a major version bump.
attachDebugInfo?
- Type:
optionalattachDebugInfo:AttachDebugOptions
Attach debug information to the output bundle.
Available modes:
none: No debug information is attached.simple: Attach comments indicating which files the bundled code comes from. These comments could be removed by the minifier.full: Attach detailed debug information to the output bundle. These comments are using legal comment syntax, so they won't be removed by the minifier.
WARNING
You shouldn't use full in the production build.
Default
'simple'chunkImportMap?
- Type:
optionalchunkImportMap:boolean| {baseUrl?:string;fileName?:string; }
Enables automatic generation of a chunk import map asset during build.
This map only includes chunks with hashed filenames, where keys are derived from the facade module name or primary chunk name. It produces stable and unique hash-based filenames, effectively preventing cascading cache invalidation caused by content hashes and maximizing browser cache reuse.
The output defaults to importmap.json unless overridden via fileName. A base URL prefix (default "/") can be applied to all paths. The resulting JSON is a valid import map and can be directly injected into HTML via <script type="importmap">.
Example
{
experimental: {
chunkImportMap: {
baseUrl: '/',
fileName: 'importmap.json'
}
},
plugins: [
{
name: 'inject-import-map',
generateBundle(_, bundle) {
const chunkImportMap = bundle['importmap.json'];
if (chunkImportMap?.type === 'asset') {
const htmlPath = path.resolve('index.html');
let html = fs.readFileSync(htmlPath, 'utf-8');
html = html.replace(
/<script\s+type="importmap"[^>]*>[\s\S]*?</script>/i,
`<script type="importmap">${chunkImportMap.source}</script>`
);
fs.writeFileSync(htmlPath, html);
delete bundle['importmap.json'];
}
}
}
]
}TIP
If you want to learn more, you can check out the example here: examples/chunk-import-map
Default
falsechunkModulesOrder?
- Type:
optionalchunkModulesOrder:ChunkModulesOrder
Control which order should use when rendering modules in chunk.
Available options:
exec-order: Almost equivalent to the topological order of the module graph, but specially handling when module graph has cycle.module-id: This is more friendly for gzip compression, especially for some javascript static asset lib (e.g. icon library)
NOTE
Try to sort the modules by their module id if possible(Since rolldown scope hoist all modules in the chunk, we only try to sort those modules by module id if we could ensure runtime behavior is correct after sorting).
Default
'exec-order'devMode?
- Type:
optionaldevMode:DevModeOptions
disableLiveBindings?
- Type:
optionaldisableLiveBindings:boolean
Disable live bindings for exported variables.
Default
falseincrementalBuild?
- Type:
optionalincrementalBuild:boolean
Enable incremental build support. Required to be used with watch mode.
Default
falsenativeMagicString?
- Type:
optionalnativeMagicString:boolean
Use native Rust implementation of MagicString for source map generation.
MagicString is a JavaScript library commonly used by bundlers for string manipulation and source map generation. When enabled, rolldown will use a native Rust implementation of MagicString instead of the JavaScript version, providing significantly better performance during source map generation and code transformation.
Benefits
- Improved Performance: The native Rust implementation is typically faster than the JavaScript version, especially for large codebases with extensive source maps.
- Background Processing: Source map generation is performed asynchronously in a background thread, allowing the main bundling process to continue without blocking. This parallel processing can significantly reduce overall build times when working with JavaScript transform hooks.
- Better Integration: Seamless integration with rolldown's native Rust architecture.
Example
export default {
experimental: {
nativeMagicString: true
},
output: {
sourcemap: true
}
}NOTE
This is an experimental feature. While it aims to provide identical behavior to the JavaScript implementation, there may be edge cases. Please report any discrepancies you encounter. For a complete working example, see examples/native-magic-string
Default
falseonDemandWrapping?
- Type:
optionalonDemandWrapping:boolean
Enable on-demand wrapping of modules.
Default
falseresolveNewUrlToAsset?
- Type:
optionalresolveNewUrlToAsset:boolean
When enabled, new URL() calls will be transformed to a stable asset URL which includes the updated name and content hash. It is necessary to pass import.meta.url as the second argument to the new URL constructor, otherwise no transform will be applied.
WARNING
JavaScript and TypeScript files referenced via new URL('./file.js', import.meta.url) or new URL('./file.ts', import.meta.url) will not be transformed or bundled. The file will be copied as-is, meaning TypeScript files remain untransformed and dependencies are not resolved.
The expected behavior for JS/TS files is still being discussed and may change in future releases. See #7258 for more context.
Example
// main.js
const url = new URL('./styles.css', import.meta.url);
console.log(url);
// Example output after bundling WITHOUT the option (default)
const url = new URL('./styles.css', import.meta.url);
console.log(url);
// Example output after bundling WITH `experimental.resolveNewUrlToAsset` set to `true`
const url = new URL('assets/styles-CjdrdY7X.css', import.meta.url);
console.log(url);Default
falsestrictExecutionOrder?
- Type:
optionalstrictExecutionOrder:boolean
Lets modules be executed in the order they are declared.
This is done by injecting runtime helpers to ensure that modules are executed in the order they are imported. External modules won't be affected.
WARNING
Enabling this option may negatively increase bundle size. It is recommended to use this option only when absolutely necessary.
Default
falsetransformHiresSourcemap?
- Type:
optionaltransformHiresSourcemap:boolean|"boundary"
Enable high-resolution source maps for transform operations.
Default
falseviteMode?
- Type:
optionalviteMode:boolean
Enable Vite compatible mode.
Default
falseInherited from
external?
- Type:
optionalexternal:ExternalOption
Specifies which modules should be treated as external and not bundled. External modules will be left as import statements in the output.
Examples
String pattern
export default {
external: 'react',
};Regular expression
export default {
external: /node_modules/,
};Array of patterns
export default {
external: ['react', 'react-dom', /^lodash/],
};In-depth
⚠️ Don't use function unless you have to
Using the function form has significant performance overhead because Rolldown is written in Rust and must call JavaScript functions from Rust for every module in your dependency graph.
Performance Impact:
- Each module triggers a Rust-to-JS call
- Cross-language call overhead is high
- Can significantly slow down builds in large projects
Use static patterns when possible:
// ❌ Avoid: Function with performance overhead
export default {
external: (id) => {
return !id.startsWith('.') && !id.startsWith('/');
},
};
// ✅ Prefer: Static pattern (much faster)
export default {
external: [
'react',
'react-dom',
'vue',
/^lodash/,
/^@mui/,
],
};When to use function:
- You need truly dynamic logic based on
parentIdorisResolved - The logic cannot be expressed with static patterns
- You're okay with the performance trade-off
⚠️ Don't use /node_modules/ to match npm packages
Using /node_modules/ to externalize npm packages is problematic because Rolldown matches module IDs twice during resolution.
Example with import Vue from 'vue':
First match (unresolved ID):
'vue'- Pattern
/node_modules/does NOT match - This is the bare package name
- Pattern
Second match (resolved ID):
'/path/to/project/node_modules/vue/dist/vue.runtime.esm-bundler.js'- Pattern
/node_modules/DOES match - This is the full resolved file path
- Pattern
The Problem:
Since the pattern only matches on the resolved ID, Rolldown generates imports with absolute paths:
// ❌ Bad result: Absolute path in output
import Vue from '/Users/somebody/project/node_modules/vue/dist/vue.runtime.esm-bundler.js';This breaks portability and doesn't work as intended.
Better alternatives:
- Use exact package names
export default defineConfig({
external: ['vue', 'react', 'react-dom'],
});- Use package name patterns
export default {
external: [/^vue/, /^react/, /^@mui/],
};- Match bare identifiers
Pattern (visualize) to match all bare module IDs (not starting with . or /):
export default {
external: /^[^./]/,
};Inherited from
input?
- Type:
optionalinput:InputOption
Defines entries and location(s) of entry modules for the bundle. Relative paths are resolved based on the cwd option.
Examples
Single entry
export default defineConfig({
input: 'src/index.js',
});Multiple entries
export default defineConfig({
input: ['src/index.js', 'src/vendor.js'],
});Named multiple entries
export default defineConfig({
input: {
'index': 'src/index.js',
'utils': 'src/utils/index.js',
'components': 'src/components/index.js',
},
});In-depth
input allows you to specify one or more entries with names for the bundling process.
When multiple entries are specified (either as an array or an object), Rolldown will create separate entry chunks for each entry.
Inherited from
logLevel?
- Type:
optionallogLevel:LogLevelOption
Controls the verbosity of console logging during the build.
Default
'info'Inherited from
makeAbsoluteExternalsRelative?
- Type:
optionalmakeAbsoluteExternalsRelative:MakeAbsoluteExternalsRelative
Inherited from
InputOptions.makeAbsoluteExternalsRelative
moduleTypes?
- Type:
optionalmoduleTypes:ModuleTypes
Maps file patterns to module types, controlling how files are processed. This is conceptually similar to esbuild's loader option, allowing you to specify how different file extensions should be handled.
Inherited from
onLog?
- Type:
optionalonLog:OnLogFunction
Custom handler for logs. Called for each log message before it's written to the console.
Inherited from
onwarn?
- Type:
optionalonwarn:OnwarnFunction
Custom handler for warnings during the build process.
Deprecated
Deprecated
This is a legacy API. Consider using onLog instead for better control over all log types.
Migration to onLog
To migrate from onwarn to onLog, check the level parameter to filter for warnings:
// Before: Using `onwarn`
export default {
onwarn(warning, defaultHandler) {
// Suppress certain warnings
if (warning.code === 'CIRCULAR_DEPENDENCY') return;
// Handle other warnings with default behavior
defaultHandler(warning);
},
};// After: Using `onLog`
export default {
onLog(level, log, defaultHandler) {
// Handle only warnings (same behavior as `onwarn`)
if (level === 'warn') {
// Suppress certain warnings
if (log.code === 'CIRCULAR_DEPENDENCY') return;
// Handle other warnings with default behavior
defaultHandler(level, log);
} else {
// Let other log levels pass through
defaultHandler(level, log);
}
},
};Inherited from
optimization?
- Type:
optionaloptimization:OptimizationOptions
Configure optimization features for the bundler.
Inherited from
output?
- Type:
optionaloutput:OutputOptions|OutputOptions[]
platform?
- Type:
optionalplatform:"node"|"browser"|"neutral"
Expected platform where the code run.
When the platform is set to neutral:
- When bundling is enabled the default output format is set to esm, which uses the export syntax introduced with ECMAScript 2015 (i.e. ES6). You can change the output format if this default is not appropriate.
- The main fields setting is empty by default. If you want to use npm-style packages, you will likely have to configure this to be something else such as main for the standard main field used by node.
- The conditions setting does not automatically include any platform-specific values.
Default
- 'node' if the format is 'cjs'
- 'browser' for other formats
Examples
Browser platform
export default {
platform: 'browser',
output: {
format: 'esm',
},
};Node.js platform
export default {
platform: 'node',
output: {
format: 'cjs',
},
};Platform-neutral
export default {
platform: 'neutral',
output: {
format: 'esm',
},
};In-depth
The platform setting provides sensible defaults for module resolution and environment-specific behavior, similar to esbuild's platform option.
'node'
Optimized for Node.js environments:
- Conditions: Includes
'node','import','require'based on output format - Main fields:
['main', 'module'] - Target: Node.js runtime behavior
- process.env handling: Preserves
process.env.NODE_ENVand other Node.js globals
'browser'
Optimized for browser environments:
- Conditions: Includes
'browser','import','module','default' - Main fields:
['browser', 'module', 'main']- prefers browser-specific entry points - Target: Browser runtime behavior
- Built-ins: Node.js built-in modules are not polyfilled by default
TIP
For browser builds, you may want to use rolldown-plugin-node-polyfills to polyfill Node.js built-ins if needed.
'neutral'
Platform-agnostic configuration:
- Default format: Always
'esm' - Conditions: Only includes format-specific conditions, no platform-specific ones
- Main fields: Empty by default - relies on package.json
"exports"field - Use cases: Universal libraries that run in multiple environments
Difference from esbuild
Notable differences from esbuild's platform option:
- The default output format is always
'esm'regardless of platform (in esbuild, Node.js defaults to'cjs') - No automatic
</script>escape behavior when platform is'browser'
Choosing a Platform
Use 'browser' when:
- Building for web applications
- Targeting modern browsers with ES modules support
- Need browser-specific package entry points
Use 'node' when:
- Building server-side applications
- Creating CLI tools
- Need Node.js-specific features and modules
Use 'neutral' when:
- Building universal libraries
- Want maximum portability
- Avoiding platform-specific assumptions
Inherited from
plugins?
- Type:
optionalplugins:RolldownPluginOption
Inherited from
preserveEntrySignatures?
- Type:
optionalpreserveEntrySignatures:false|"strict"|"allow-extension"|"exports-only"
Controls how entry chunk exports are preserved. This determines whether Rolldown needs to create facade chunks (additional wrapper chunks) to maintain the exact export signatures of entry modules, or whether it can combine entry modules with other chunks for optimization.
Default
'strict'
Values
'exports-only'
Follows 'strict' behavior for entry modules that have exports, but allows 'allow-extension' behavior for entry modules without exports. This provides a good balance between maintaining export signatures and optimization flexibility.
'strict'
Entry chunks will exactly match the exports of their corresponding entry modules. If additional internal bindings need to be exposed (for example, when modules are shared between chunks), Rolldown will create facade chunks to maintain the exact export signature.
Use case: This is the recommended setting for libraries where you need guaranteed, stable export signatures.
'allow-extension'
Entry chunks can expose all exports from the corresponding entry module, and may also include additional exports from other modules if they're bundled together. This allows more optimization opportunities but may expose internal implementation details.
false
Provides maximum flexibility. Entry chunks can be merged freely with other chunks regardless of export signatures. This can lead to better optimization but may change the exposed exports significantly.
Understanding Facade Chunks
A facade chunk is a small wrapper chunk that Rolldown creates to preserve the exact export signature of an entry module when the actual implementation has been bundled into another chunk.
Example scenario:
If you have two entry points that share code, and preserveEntrySignatures is set to 'strict', Rolldown might:
- Bundle the shared code into a common chunk
- Create facade chunks for each entry point that re-export from the common chunk
- This ensures each entry point maintains its exact original export signature
In-depth
Override per Entry Point
The preserveEntrySignatures option is a global setting. The only way to override it for individual entry chunks is to use the plugin API and emit those chunks via this.emitFile instead of using the input option.
Practical Example: Mixed Library and Application Build
// rolldown.config.js
export default {
preserveEntrySignatures: 'exports-only', // Default for most entries
plugins: [
{
name: 'custom-entries',
buildStart() {
// Library entry that needs strict signature preservation
this.emitFile({
type: 'chunk',
id: 'src/library/index.js',
fileName: 'library.js',
preserveEntrySignature: 'strict',
});
// Application entry that can be optimized
this.emitFile({
type: 'chunk',
id: 'src/app/main.js',
fileName: 'app.js',
preserveEntrySignature: false,
});
},
},
],
};When using this.emitFile with type 'chunk', you can specify:
preserveEntrySignature: Override the global settingfalse: Maximum optimization, merge chunks freely'strict': Exact export signature preservation'allow-extension': Allow additional exports from merged chunks'exports-only': Strict only for modules with exports
fileName: Custom output filename for the entry chunkid: Module ID or path to use as the entry point
When to Use Each Setting
'strict': Building libraries, need guaranteed export signatures'exports-only': Most applications, balanced approach (default)'allow-extension': Advanced optimizations, okay with exposing extra exportsfalse: Maximum bundle size reduction, export signatures don't matter
Inherited from
InputOptions.preserveEntrySignatures
resolve?
- Type:
optionalresolve:object
alias?
- Type:
optionalalias:Record<string,string|false|string[]>
Example
resolve: {
alias: {
'@': '/src',
'utils': './src/utils',
}
}WARNING
resolve.alias will not call resolveId hooks of other plugin. If you want to call resolveId hooks of other plugin, use viteAliasPlugin from rolldown/experimental instead. You could find more discussion in this issue
aliasFields?
- Type:
optionalaliasFields:string[][]
Fields in package.json to check for aliased paths.
conditionNames?
- Type:
optionalconditionNames:string[]
Condition names to use when resolving exports in package.json. Defaults based on platform and import kind:
- Browser platform:
["import", "browser", "default"]for import statements,["require", "browser", "default"]for require() calls - Node platform:
["import", "node", "default"]for import statements,["require", "node", "default"]for require() calls - Neutral platform:
["import", "default"]for import statements,["require", "default"]for require() calls
exportsFields?
- Type:
optionalexportsFields:string[][]
Fields in package.json to check for exports.
extensionAlias?
- Type:
optionalextensionAlias:Record<string,string[]>
Map of extensions to alternative extensions.
With writing import './foo.js' in a file, you want to resolve it to foo.ts instead of foo.js. You can achieve this by setting: extensionAlias: { '.js': ['.ts', '.js'] }.
extensions?
- Type:
optionalextensions:string[]
Extensions to try when resolving files. These are tried in order from first to last.
Default
['.tsx', '.ts', '.jsx', '.js', '.json']mainFields?
- Type:
optionalmainFields:string[]
Fields in package.json to check for entry points. Defaults based on platform:
- Node:
['main', 'module'] - Browser:
['browser', 'module', 'main'] - Neutral:
[](relies on exports field)
mainFiles?
- Type:
optionalmainFiles:string[]
Filenames to try when resolving directories.
Default
['index']modules?
- Type:
optionalmodules:string[]
Directories to search for modules.
Default
['node_modules']symlinks?
- Type:
optionalsymlinks:boolean
Whether to follow symlinks when resolving modules.
Default
truetsconfigFilename?
- Type:
optionaltsconfigFilename:string
Deprecated
Use the top-level tsconfig option instead.
Inherited from
shimMissingExports?
- Type:
optionalshimMissingExports:boolean
When true, creates shim variables for missing exports instead of throwing an error.
Default
false
Examples
Enable shimming
export default {
shimMissingExports: true,
};Example scenario
module-a.js:
export { nonExistent } from './module-b.js';module-b.js:
// nonExistent is not actually exported here
export const something = 'value';With shimMissingExports: false (default), this would throw an error. With shimMissingExports: true, Rolldown will create a shim variable:
// Bundled output (simplified)
const nonExistent = undefined;
export { nonExistent, something };Inherited from
InputOptions.shimMissingExports
transform?
- Type:
optionaltransform:TransformOptions
Configure how the code is transformed. This process happens after the transform hook.
To transpile legacy decorators, you could use
export default defineConfig({
transform: {
decorator: {
legacy: true,
},
},
})For latest decorators proposal, rolldown is able to bundle them but doesn't support transpiling them yet.
Inherited from
treeshake?
- Type:
optionaltreeshake:boolean|TreeshakingOptions
Controls tree-shaking (dead code elimination). When true, unused code will be removed from the bundle to reduce bundle size.
Default
trueInherited from
tsconfig?
- Type:
optionaltsconfig:string|true
Configures TypeScript configuration file resolution and usage.
Options
Auto-discovery mode (true)
When set to true, Rolldown enables auto-discovery mode (similar to Vite). For each module, both the resolver and transformer will find the nearest tsconfig.json.
If the tsconfig has references and certain conditions are met (the file extension is allowed and the tsconfig's include/exclude patterns don't match the file), then the referenced tsconfigs will be searched for a match. If no match is found, it falls back to the original tsconfig.
export default {
tsconfig: true,
};Explicit path (string)
Specifies the path to a specific TypeScript configuration file. You may provide a relative path (resolved relative to cwd) or an absolute path.
If the tsconfig has references, this mode behaves like auto-discovery mode for reference resolution.
export default {
tsconfig: './tsconfig.json',
};export default {
tsconfig: '/absolute/path/to/tsconfig.json',
};TIP
Rolldown respects references and include/exclude patterns in tsconfig, while esbuild does not. If you need esbuild-compatible behavior, specify a tsconfig without references. You can use extends to share the options between the two.
What's used from tsconfig
When a tsconfig is resolved, Rolldown uses different parts for different purposes:
Resolver
Uses the following for module path mapping:
compilerOptions.paths: Path mapping for module resolutioncompilerOptions.baseUrl: Base directory for path resolution
Transformer
Uses select compiler options including:
jsx: JSX transformation modeexperimentalDecorators: Enable decorator supportemitDecoratorMetadata: Emit decorator metadataverbatimModuleSyntax: Module syntax preservationuseDefineForClassFields: Class field semantics- And other TypeScript-specific options
Example
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"jsx": "react-jsx",
"baseUrl": ".",
"paths": {
"@/*": ["src/*"],
"@components/*": ["src/components/*"]
}
}
}With this configuration:
- JSX will use React's automatic runtime
- Path aliases like
@/utilswill resolve tosrc/utils
Priority
Top-level transform options always take precedence over tsconfig settings:
export default {
tsconfig: './tsconfig.json', // Has jsx: 'react-jsx'
transform: {
jsx: {
mode: 'classic', // This takes precedence
},
},
};TIP
For TypeScript projects, it's recommended to use tsconfig: true for auto-discovery or specify an explicit path to ensure consistent compilation behavior and enable path mapping.
Default
undefined (no tsconfig resolution)Inherited from
watch?
- Type:
optionalwatch:false|WatcherOptions