npm / rollup
rollup
What changed in rollup 4, from its official release notes, upgrade guides and advisories. Sources checked 2026-10-18.
1 breaking1 security1 deprecations2 new APIs and options3 performance6 behavior and defaults52 fixes and other
See which of these apply to your code, ranked, in your agent:
npx @unstale/cli initrollup 466 changes
Breaking changes 1
Rollup throws if the generated bundle contains paths that would leave the output directory.
Security 1
Rollup 4 has Arbitrary File Write via Path Traversal
Deprecations 1
Returning import attributes from load or transform hooks is deprecated and will no longer be supported with Rollup 5.
New APIs and options 2
Rollup supports source phase imports as long as they are external.
Import attributes are now available in plugin hooks that did not provide them before.
Performance 3
Rendering ES output is slightly faster by avoiding repeated export name scans when rendering ES chunks.
Unused Symbol.hasInstance, Symbol.dispose and Symbol.asyncDispose properties can now be tree-shaken.
Caching generated variable names improves rendering performance.
Behavior and default changes 6
Try-catch deoptimization now covers calling methods on objects, retaining callbacks of helper methods called from try statements.
Rollup can analyze function return values in more cases, which may affect build-time analysis.
Static dependencies shared between manual chunks and entry points are extracted into separate chunks.
Entry modules are sorted to make chunk hash names deterministic.
Rollup also supports the annotation before variable declarations that declare function expressions.
Rollup tracks object property inclusions of dynamic namespace members.
Fixes and other changes 52
Live-bindings are now properly maintained for aliased exports.
Typed array constructor calls are retained when their argument has iteration side effects.
Chunk hashes now change when sourcemap comments change, avoiding stale hashes when those comments are modified.
Fixes some relative import resolution edge cases, matching Node's join and relative behavior for "." and ".." segments in the browser.
Fixes watching not-yet-created files from plugins when several share a directory.
Side effects in class instance field initializers are retained when instantiating a class, avoiding incorrect tree-shaking.
Detection now recognizes top-level asynchronous for...of loops and async disposal.
Prevents cycles when using indirect top-level await for dynamic imports.
The Rollup WASM build is supported on big-endian hosts.
Fixes a performance regression when bundling code with deeply nested property calls.
When build errors occur, errors from closeBundle no longer replace them.
Certain CoreJS helpers are no longer wrongly tree-shaken.
Fixes cases where some core-js feature-detections were not triggering properly.
External re-exports used in a reified dynamic namespace are now always imported.
Watch mode now terminates when closed via Ctrl+C instead of hanging.
Watch mode no longer starts overlapping runs when plugins invalidate files at the wrong time.
Watch mode events are now emitted to listeners correctly in edge cases, especially when errors occur.
Quotes and backslashes in import attribute values are escaped so Rollup does not generate invalid code.
Cached module meta information is now exposed in shouldTransformCachedModule, allowing plugins to access it during cache checks.
The browser shims for basename and extname now fully match NodeJS.
Tree-shaking respects Windows line terminators when removing line breaks needed to prevent automatic semicolon insertion.
Failures on invalidation are always reported and recovered from in watch mode.
Fixes filtering logs by nested properties via the CLI when those properties have primitive values.
Function return value tracking was reverted until the most recent issue is understood.
Fixes invalid module concatenations that could result from compact mode.
Resolves a regression when using Rollup on older Linux distributions and enforces glibc ≤ 2.28 compatibility.
Illegal characters in the preserved modules input base are sanitized before computing preserved module chunk names.
When using minChunkSize with hoisting disabled, Rollup no longer adds spurious side-effect-free external imports to chunks.
Fix an issue where getLogFilter would match additional logs.
Preserve multipart file extensions when deconflicting output chunks by inserting conflict numbers before the first extension.
Avoids extraneous newlines when adding headers via plugins.
Fixes a rare issue where starting Rollup would hang on Windows.
Chunk assignment is stabilized across parallel file reads, improving the stability of chunk hashes.
Fixes variable rendering when generating different formats from the same build.
Fixes a caching issue that could cause side effect imports to be dropped.
Fixes a crash when using lazy dynamic imports with moduleSideEffects:false.
Ensures exports of a dynamic import are fully included when called from a try...catch.
Fixes a heap corruption issue on Windows.
Rollup handles methods that access dynamically imported namespace members via this.
Fixes the semicolon insertion position in JSX variable declarations.
Manual chunks are sorted by module execution order to reduce circular dependency issues.
Fixes the artifact reference for OpenBSD, so developers can use the correct release artifact.
Namespace properties referenced only from a try-catch are included.
Well-known-Symbol-valued properties are no longer tree-shaken except in select cases.
Fixes the semicolon insertion position when using JSX.
Generates spec-compliant sourcemaps when sources content is excluded by setting sourcesContent to undefined instead of null.
Rollup no longer removes Symbol.asyncDispose properties with (await) using declarations.
Rollup no longer removes Symbol.dispose properties with (await) using declarations.
Fixes assignments being wrongly tree-shaken when they mutate a value.
Fixes an error that flagged too many modules as having an unused external import.
Rollup no longer throws when using invalid escape sequences in template literals.
Sourcemap debugIds are now always valid UUIDs, avoiding invalid-length identifiers.