npm / svelte
svelte
What changed in svelte 5, from its official release notes, upgrade guides and advisories. Sources checked 2026-10-18.
14 breaking14 security19 new APIs and options17 performance15 behavior and defaults1 tooling316 fixes and other
See which of these apply to your code, ranked, in your agent:
npx @unstale/cli initsvelte 5396 changes
Breaking changes 14
Using let: directives on a component with a children snippet now errors.
Calling setContext after an await during SSR throws set_context_after_init.
Declaration tags and {@const} are blocked on async values read inside closures.
This error is now reported for export let x = $derived(...) in runes mode.
Duplicate snippet or declaration tag definitions now produce a compile-time error.
The async
blockingstrategy is replaced withmerging.The introstart event is no longer dispatched for an animation of the animate directive.
The
idPrefixoption no longer accepts--.The error is now emitted in production.
SvelteKit data attributes were removed from the element type declarations.
Calling the get function for an unset createContext value on the server now throws.
Invalid {@tag}s now throw.
These await expressions now produce an error at compile time instead of at runtime.
Reactivity context is no longer preserved across function boundaries.
Security 14
The regular expression handling was hardened.
Svelte: ReDoS in
<svelte:element>Tag ValidationSvelte SSR vulnerable to cross-site scripting via spread attributes
Svelte: SSR XSS via Insecure Promise Serialization in hydratable
Svelte Vulnerable to XSS via DOM Clobbering of Internal Framework State
Svelte vulnerable to XSS during SSR with contenteditable
bind:innerTextandbind:textContentSvelte: XSS via HTML Comment Injection in SSR Error Boundary Hydration Markers
Svelte affected by cross-site scripting via spread attributes in Svelte SSR
Svelte affected by XSS in SSR
<option>elementSvelte SSR attribute spreading includes inherited properties from prototype chain
Svelte SSR does not validate dynamic element tag names in
<svelte:element>Template-literal-special characters in SSR attribute values are sanitized.
HTML handling uses TrustedTypes where supported.
svelte vulnerable to Cross-site Scripting
New APIs and options 19
Exported from svelte/server for use by developers.
Added to SvelteMap.
Added to SvelteMap.
Added as a function to createContext.
Exported from svelte/server for use by developers.
The defaultValue option is now supported on select elements.
Exported from svelte/server for use by developers.
Exported from svelte/server for use by developers.
The print option indent is now available.
Exports TweenOptions, SpringOptions, SpringUpdateOptions and Updater from svelte/motion.
The custom element shadow option now accepts a ShadowRootInit object.
Export parseCss from svelte/compiler so it can be imported by developers.
Select elements can now be customized.
Adds a csp option to render(...), and emits hashes when using hydratable.
Adds the print function.
Adds the hydratable API.
Adds out-of-order rendering.
An experimental fork API is available.
Adds the
$state.eager(value)rune.
Performance 17
Parser interactions with Acorn are faster or avoided where possible.
Regex matching is avoided in the parser where possible.
SSR rendering reduces render-result garbage collection.
Map lookups for legacy reactive statement ordering change from O(n²) to O(n).
The option/select value guard reuses its cached value.
Make async blocker analysis scale linearly with the number of top-level references.
Compilation skips unnecessary blocker analysis for components without top-level await.
Walk
composedPath()directly during delegated event propagation.Avoids re-traversing the effect tree after
$:assignments.Caches element interactivity and source line splitting in the compiler.
Optimizes CSS selector pruning.
Avoids O(n²) name scanning in scope generate and unique.
The compiler analysis phase is optimized.
Parser hot paths are optimized for faster compilation.
Already settled promises no longer incur async overhead.
Tracing is used less eagerly during development.
Await expressions are optimized more effectively.
Behavior and default changes 15
Declarations are now allowed in the template.
The css compiler option can now be a function.
The customElement compiler option can now be a function.
The runes compiler option can now be a function.
Comments are now allowed in tags, expanding the syntax developers can write.
Error boundaries now work on the server.
Supports TrustedHTML in {@html} expressions.
Effects are proactively deferred in a pending boundary, changing when they run.
Can now be used when instantiating components programmatically.
The assignment_value_stale warning is issued more conservatively.
Adds more CSS selectors to print().
The state_referenced_locally diagnostic now applies to props.
Attachments and attribute effects are no longer executed eagerly.
The restriction against calling flushSync in effects has been lifted.
Vite optimized deps are excluded from stack traces, making those traces less cluttered.
Tooling 1
Provides a proper public type for the parseCss result.
Fixes and other changes 316
A redundant link role is no longer warned about on area elements without an href.
Await blocks with only a pending branch are printed correctly.
Await wrappers preserve location information.
Removing the focused element while using bind:activeElement no longer throws state_unsafe_mutation.
Stale boundary reset callbacks are ignored.
Hydration state is restored if a custom element attribute update throws.
Deferred transitions aborted before initialization are handled.
Reconnecting deriveds no longer creates duplicate subscriptions.
Dynamic element connections are preserved during hydration.
Each-block commits read the batch-local array.
Compilation errors if
{:else}is followed by another{:else}or{:else if ...}.Event handlers assigned after top-level await are attached in production.
Pending work is flushed before the flushSync callback is invoked.
Hydration recovers if an unexpected node replaces a nested boundary comment.
Error boundaries no longer intercept hydration mismatch recovery.
When migration cannot turn a reactive assignment into a declaration, it keeps the assignment even when it has no dependencies.
Migration no longer hangs on a declaration sharing a line with its script tag.
Compilation errors when a declaration in a snippet redeclares one of its parameters.
An unchanged spread value is no longer overwritten, preserving incomplete number input.
URL updates no longer track SvelteURLSearchParams.
Components destroyed while waiting for top-level await no longer create async deriveds.
Untracked derived reads no longer retain disconnected dependencies.
aria-braillelabel is recognized as a known ARIA attribute.
aria-brailleroledescription is recognized as a known ARIA attribute.
Deferred event listeners are cancelled during cleanup.
The fallback of an each block resolves in the enclosing scope.
Effect trees of batches no longer interfere with each other.
Global CSS is preserved in components without scopable elements.
Input default values are serialized during server rendering.
Object.hasOwn reacts to ownership changes on state proxies.
$state.eager is preserved when used as a variable initializer.
The accessibility check now accepts onfocusin and onfocusout.
Line feed character references are preserved in attribute values.
Omitted from SSR output because it has no HTML attribute.
Preserved on hydrated radio inputs with spread attributes.
Teardown errors are routed through invoke_error_boundary.
CSS tree-shaking is avoided for exported Snippet.
They are measured before their starting styles are applied.
Uppercase-X hexadecimal numeric character references are decoded.
Callbacks run when a server render throws.
No longer fires twice when compilerOptions.hmr is true.
They are no longer resurrected when an ancestor block is paused and resumed.
Dependencies of a reaction that throws are kept, preventing deriveds it read from being leaked or stuck in their error.
Static value attributes no longer produce malformed AST output.
Mutating selectedcontent no longer changes the selected option.
Warnings are now emitted for undeclared shorthand event handlers on svelte:window, svelte:document, and svelte:body.
The transition no longer produces NaN keyframe values for elements without a layout box.
Failed snippets are scoped to their boundary.
Component instances stored in $state are no longer turned into state proxies.
Template store subscriptions are blocked on the promise that assigns the store.
Rendering of Svelte custom element slots is more robust.
Anchors are removed on unmount.
Elements inside svelte:head no longer receive a class hash.
Snapshots are now tracked in reactions.
The port signal is synchronized when the protocol setter clears the port.
Static textarea value attributes are properly applied during CSR.
Correctly print await blocks with catch clauses.
Apply CSS custom properties with falsy values on components.
Preserve CSS escape sequences when printing selectors.
Preserve namespaces in CSS type selectors.
Allow custom elements to receive async values as props.
Avoid double-calling a derived reference when destructuring
$derivedof another$derivedduring server-side rendering.Give effect teardowns the value from before the first write in a flush.
Release
last_propagated_eventafter propagation settles so it no longer retains the last event's target subtree.Strip comments from inline style values in linear time.
Transform expressions inside labeled statements during server compilation.
Ignore Program node comments during migration.
Parse
:nth-child(2n of.foo)whenofis not followed by whitespace.Increment private state fields through a non-
thisreceiver and preserve short-circuiting for logical assignments.Clean up removed capture event handlers from spread attributes.
Comments in attributes are no longer duplicated.
The controlled each fast path is skipped while another batch is pending, fixing behavior in that situation.
The AST printer now preserves CSS comments.
Whitespace handling inside the printer was improved.
Hydrating a failed boundary now calls onerror and provides a working reset.
Reset now works when hydrating a failed boundary.
Select selection is now preserved when spread attributes omit value.
A derived with an abort controller is rerun when it reconnects.
Declaration tags no longer trigger a warning in event handlers.
Declaration tags are correctly transformed during SSR.
Declaration tags are no longer treated as parts inside each blocks.
Deriveds read inside branch or root effects are no longer incorrectly reconnected.
An unnecessary derived effect is skipped in an earlier batch.
A derived's own AbortSignal is aborted when it disconnects.
Computed keys in keyed each-block destructuring patterns are now transformed correctly.
Sourcemaps are chained with an empty
sources[0]instead of being dropped.The compiler now correctly transforms
$state.eager()for SSR output.Clearing the previous task reference after abort prevents a memory leak on interrupted tweens.
The declarator end position now includes wrapping parentheses, improving source position information for {@const} declarations.
Reactivity context is now always unset after being restored, preventing context from being left set.
Optional parameters are stripped so the generated JavaScript is valid.
Subscribers are no longer notified when the URL changes without affecting the search string.
Errors that occur in destroyed effects are now ignored.
BigInts in
$state.snapshot(...)return values are now correctly typed.Declaration tags are ignored for the animation directive.
Pending async deriveds are rejected when discarded.
Declaration tag contents are parsed more robustly, including when they contain
type.References to earlier declarators in a declaration tag are transformed correctly.
The compiler no longer emits spurious
state_referenced_locallywarnings for$deriveddeclarations in declaration tags.Whitespace before
letorconstin declaration tags is now tolerated.Reference checks for blockers now run on the server as well.
Setting duplicate keys to the same joined value now updates
SvelteURLSearchParamscorrectly.Parsing no longer enters an infinite loop when a tag expression ends with a trailing
/at end of input.Newlines in spread input values are preserved when the
typeattribute followsvalue.Include the tag name in this accessibility warning.
Correctly coordinate component-level effects inside async blocks.
Async blockers propagate through closure references, so template expressions correctly wait for awaited values.
Allow
$derived(await ...)in disconnected effect roots.Declare
let:directives before{@const}declarations on slotted elements.Resume branches that were kept around after being outro-ed.
Avoid emitting a waterfall warning when an async operation resolves to the same value.
Promise-ifies
{#await await ...}expressions on the server and correctly hydrates them on the client.An uninitialized derived now executes even if it has been destroyed.
Context is unset synchronously in run.
Teardown effects no longer run when deriveds are unfrozen.
Empty attribute names are disallowed during SSR.
Updating
bind:thisaccounts for proxified instances.Component member expressions compile correctly for SSR.
Comments are ignored when reading CSS values.
@debugtags can reference awaited variables.Eager effects are flushed in production.
Errors from failed iterables are rethrown after calling
return().Fallback props rerun when their dependencies update.
False-positive errors from
$inspectdependencies are ignored.Running obsolete async branches are aborted.
The typings allow
nullforpending.Promise.allis wrapped insaveduring SSR.Context is reapplied after an error is transformed during SSR.
Stale deriveds resolve with the latest value.
Stale promises are left to wait for a later resolution instead of being rejected.
Dependencies of
$state.eager/pendingare kept.Deriveds are no longer marked while an effect is updating.
Child effect roots are no longer marked as inert.
Context is reset after waiting on blockers of @const expressions.
New eager effects continue to be flushed.
Blockers for @const are now calculated correctly.
Deriveds are frozen once their containing effects are destroyed.
HMR updates for dynamic components are now handled properly.
Error boundary rendering is deferred in forks.
Prevents a false-positive reactivity loss warning.
In legacy mode, @const tags are invalidated based on visible references.
In dev mode,
$destroy,set, andoninstance methods are no longer overridden.Types for
ontoggleon<details>elements are corrected.Parentheses in template expressions are handled more robustly.
Improves the error message for duplicate module imports.
New effects are rescheduled in prior batches.
Prevents a hydration error when using async {@html ...}.
Bindings are now correctly handled on the server.
Forwards the correct start and end nodes to the active effect.
Defers batch resolution until earlier intersecting batches have committed.
Fixes hydration comments during HMR, addressing incorrect hydration behavior during hot module replacement.
Properly invokes iterator.return() during the reactivity loss check.
Reactivity loss tracking has been reinstated.
Nodes are removed in a boundary when work is pending and HMR is active.
Using $inspect after top-level await no longer breaks builds.
Batches made obsolete by a commit are discarded.
Inert effects resume when they come from offscreen.
The standalone-child state is correctly reset.
Templates no longer eagerly access functions that have not yet been initialized.
Handles asynchronous right-hand sides in assignment_value_stale.
Ensures derived values remain correct across batches.
Updates the select’s internal value on change, fixing select value behavior.
Lazily evaluates the right-hand side when checking for assignment_value_stale.
Recovers from errors that leave the effect tree corrupted.
Resolves the boundary in the correct batch during hydration.
Removes a circular dependency involving untrack.
Batches are re-processed when new root effects are scheduled.
Improves cleanup timing for bind:this.
Handles async updates within a pending boundary.
{@html} no longer duplicates content inside contenteditable elements.
Preserves original boundary errors when keyed each rows are removed during async updates.
Preserves each items that are needed by pending batches.
Event handlers are always case insensitive during SSR.
Fixes incorrect handling of keys with undefined values.
The search setter now returns the normalized value, matching native URL behavior.
Default parameters no longer cause scope leaks.
Flushed effects no longer run again.
If blocks hydrate correctly.
Server context is set after async transformError.
The :catch branch of an #await block now renders with the correct key.
String coercion is now consistent with toString.
Fixes update expressions on server deriveds.
Handles shadowed function names correctly.
Head effects are now kept in the effect tree.
TrustedHTML is used to test for customizable <select> support where necessary.
Repairs truthy/falsy hydration mismatches for dynamic components.
Re-runs non-render-bound deriveds on the server.
Fixes miscellaneous option escaping and backwards compatibility.
Event handlers are stripped during SSR.
In dev mode, non-idempotent each block keys are detected and reported as errors.
Treats CSS attribute selectors as case-insensitive for HTML enumerated attributes.
Prevents event delegation logic from conflicting between Svelte instances.
Runs effects in pending snippets.
Locates the Rollup annotation so it is friendly to JavaScript downgraders.
Dev delegated handlers now take async into consideration.
The state_referenced_locally warning is now emitted for non-destructured props.
Fixes a crash when document.contentType is undefined.
Uses symbols for encapsulated event delegation.
Delegated event handlers are preserved while one or more root components are using them.
Block-level elements are flushed into separate sequences when formatting output.
Freezes effects inside deriveds when disconnecting and unfreezes them on reconnect.
Always lowercases HTML elements for XHTML compliance.
Renders multiple and selected attributes as empty strings for XHTML compliance.
Accounts for nodeName case sensitivity on XHTML pages.
Propagates $effect errors to the boundary.
Doesn't swallow DOMException when media.play() fails.
Resolves effect_update_depth_exceeded when using bind:value on a <select> with derived state in legacy mode.
Prevents hydration mismatches for async render tags.
Boolean attribute values are rendered as empty strings for XHTML compliance.
Already-resolved async blocks are properly hydrated.
Infinite effect loops are cleared after flushing.
Key blocks now allow NaN as their key.
Accessibility role checks treat <menu> like <ul> and <ol>.
Hydration exits resolved async blocks on the correct node.
Stores in each block expressions are detected regardless of AST shape.
Avoids generating erroneous async derived expressions for blocks.
Effects inside unskipped branches are rescheduled.
Avoids Cloudflare warnings about the missing node:crypto module.
Consecutive large text nodes are merged.
Multiline HTML blocks are properly separated from each other in print output.
Prevents unhandled exceptions arising from dangling promises in script blocks.
Async functions are created in SSR output only when necessary.
Effects inside skipped branches are reset.
The introstart event fires after the specified delay.
The outrostart event fires after the specified delay.
Popover elements are disregarded when determining whether an element has content.
Updating a reaction inside a fork now preserves its old dependencies.
Signal versions are incremented when forks are discarded.
Fixes each blocks breaking when effects are interspersed among items.
Prevents unintended exports from namespaces.
Boundary onerror callbacks now run in a microtask in case they result in the boundary's destruction.
Avoids duplicating escaped characters in the CSS AST.
The warning now includes pointer and touch events.
Avoids unnecessary block effect re-runs after async work completes.
Fixes handling of false dynamic components during server-side rendering.
Fixes hydration failing with settled async blocks.
The wait function is now exported from the internal client index, making it available to importers of that index.
Resolution of async work is batched.
Code generation is improved for const tags with async dependencies.
Await expressions inside {@html} are hydrated properly.
Snippets are hoisted above const declarations in the same block, fixing their handling when declared after a const.
Handle non-string values in the this attribute.
Fixes triggering reactivity for selectedcontent.
Static elements are no longer reset when used with debug or snippets.
The subtree of a Svelte boundary is now marked as dynamic.
Hydratable keys are serialized using devalue.uneval.
Clean derived values reconnect when read in a reactive context.
Prevents an infinite loop when HMRing a component with an
await.The
currentTargettype in theonfunction is fixed.Static optimisation is skipped for stateless deriveds after
await.Fixes a race condition when importing AsyncLocalStorage.
Deferred effects are correctly rescheduled when a batch is revived after async work.
Correctly prints
!doctypeduring print.The AST root's end is set to
template.length.The AST root's start is set to 0.
Prevents erroneous
state_referenced_locallywarnings on prop fallbacks.Prevents a crash when hydratable serialization fails.
Accepts off as a valid value for the textarea wrap attribute.
srcObject is now permitted as an attribute on <audio> and <video> elements.
Svelte no longer issues an accessibility warning for a <video> without captions when it has no src.
Blocks are now correctly reconciled after outroing branches are resumed.
Items are now destroyed after their siblings are resumed.
Allows
$props.id()to occur after anawait.Keeps reactions up to date even when read outside of an effect.
Cross-realm Promises are now handled in hydratable.
Node locations are preserved to improve sourcemaps.
Fixes array destructuring after await.
Blockers are awaited before const declarations are initialized, preventing incorrect initialization behavior.
Generated code for simple destructurings is corrected.
Animations in each blocks no longer interfere with transitions.
Offscreen items and the last effect in each block are linked correctly.
Forked derived values are now stored.
Async blockers are now taken into account for bindings, transitions, animations, and attachments.
Named self-closing slots are now migrated correctly.
Derived values are no longer set during time traveling.
Maintains the correct linked list of effects when updating each blocks.
Transitions of elements that are already outroing are no longer canceled.
Prevents other batches from running while the main batch has queued root effects.
Functions are now handled correctly when determining async blockers.
Blockers are now taken into account when creating #await blocks.
Async @const in a boundary now hydrates correctly.
Async @const expressions in templates are now parallelized.
Deriveds remain reactive after their original parent effect is destroyed.
Eager effects no longer break the reactions chain.
Fixes each blocks losing reactivity when items are removed while a promise is pending.
Blockers of components are taken into account.
Deferred effects can be rescheduled later on.
Fixes batch deactivation so other batches are not deactivated.
Dependencies of async bindings are now awaited.
Async static props and attributes are now awaited.
Dependencies of style directives are now awaited.
Deriveds reconnect to the effect tree when time-travelling.
Symbols are preserved when creating derived rest properties.
The document title is deferred until async work is complete.
Forks now always access the correct values.
Each blocks with async dependencies are treated as uncontrolled.
Fixes transformation of $bindable after await expressions.
Settles a batch after DOM updates.
Fixes batch restoration in #await.
Fixes handling of <svelte:head> when rendered asynchronously.
Error messages for global variable assignments are clearer.
Calling discard on a fork after commit is ignored.
Inspect errors now have less confusing names.
setContext is now always allowed before the first await in a component.
Pending changes are flushed after rendering a failed snippet.
Mounting snippets is coordinated with await expressions.
Static blocks are now taken into account when determining transition locality.
Batches stay alive until all async work is complete.
Guards such as if, each, and key run before their contents.
$inspect logs now come from the callsite.
Fixes declaration placement by placing let: declarations before {@const} declarations.
Improves the each_key_without_as error.
Reports an error when an
eachblock has akeybut noasclause.Preserves
<select>state while the element is focused.Adds hydration markers in the pending branch of an SSR boundary.
The sync-in-async warning is removed for server rendering.