From fe46d7f3cb5debcab817c4006e22fb1b2f6f104c Mon Sep 17 00:00:00 2001 From: marwan562 Date: Sat, 22 Aug 2026 15:40:30 +0300 Subject: [PATCH] fix: simplify derived server docs per review - Remove internal implementation details (once, updated_value, push-pull) from $derived docs and server warning - Mention $derived.by alongside $derived - Remove issue link from user-facing text - Add concise no-reactivity note in first section and keep concise WARNING in Overriding section Addresses feedback from @7nik on #18686 --- documentation/docs/02-runes/03-$derived.md | 4 +++- documentation/docs/98-reference/.generated/server-warnings.md | 2 +- packages/svelte/messages/server-warnings/warnings.md | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/documentation/docs/02-runes/03-$derived.md b/documentation/docs/02-runes/03-$derived.md index d7fda2283f..2945c5be80 100644 --- a/documentation/docs/02-runes/03-$derived.md +++ b/documentation/docs/02-runes/03-$derived.md @@ -24,6 +24,8 @@ As with `$state`, you can mark class fields as `$derived`. > [!NOTE] Code in Svelte components is only executed once at creation. Without the `$derived` rune, `doubled` would maintain its original value even when `count` changes. +> [!NOTE] There is no reactivity on the server — `$derived` and `$derived.by` values do not recompute when their dependencies change, including overridden values (see [Overriding derived values](#Overriding-derived-values)). + ## `$derived.by` Sometimes you need to create complex derivations that don't fit inside a short expression. In these cases, you can use `$derived.by` which accepts a function as its argument. @@ -93,7 +95,7 @@ Derived expressions are recalculated when their dependencies change, but you can > [!NOTE] Prior to Svelte 5.25, deriveds were read-only. -> [!WARNING] Overrides behave differently between client and server. On the client, an override is temporary — it is discarded as soon as any of the derived's dependencies change, because `derived` values are tracked via the reactive graph (`push-pull` reactivity). On the server, there is no reactive graph: `svelte/server` memoizes the derived with `once(fn)` (`packages/svelte/src/internal/server/index.js:441`) and stores the override in a closure (`updated_value ?? get_value()` at `index.js:498`). Once you assign to a `derived` on the server it will **never recompute** and the override survives forever. Avoid reassigning `let`-deriveds during SSR, and be aware that shared `*.svelte.ts` modules executed in `node`/`vitest` (server codegen) will show `client: 20` vs `server: 999` in the same test — see `sveltejs/svelte#18681`. In `DEV` the server now warns when you write to a derived. +> [!WARNING] There is no reactivity on the server — when a `$derived` or `$derived.by` value's dependencies change, it will not recompute. This includes overridden values, which on the client are temporary and discarded when dependencies change, but on the server are permanent. ## Deriveds and reactivity diff --git a/documentation/docs/98-reference/.generated/server-warnings.md b/documentation/docs/98-reference/.generated/server-warnings.md index 23cd5e5922..7a9d620c1f 100644 --- a/documentation/docs/98-reference/.generated/server-warnings.md +++ b/documentation/docs/98-reference/.generated/server-warnings.md @@ -6,7 +6,7 @@ Assignment to derived state on the server is permanent and will not be recalculated when its dependencies change, unlike on the client where it is temporary ``` -This warning is emitted when you reassign a value created with `$derived` while compiling with `generate: 'server'`. On the client such overrides are temporary and discarded once dependencies change; on the server the derived is memoized with `once(fn)` and the override is stored in a closure (`updated_value`), so it survives forever. See `sveltejs/svelte#18681` for details. +This warning is emitted when you reassign a value created with `$derived` or `$derived.by` while compiling with `generate: 'server'`. There is no reactivity on the server — derived values do not recompute when dependencies change, including overridden values. On the client, overrides are temporary and discarded when dependencies change. ### unresolved_hydratable diff --git a/packages/svelte/messages/server-warnings/warnings.md b/packages/svelte/messages/server-warnings/warnings.md index 07e2db90f4..baddff37a8 100644 --- a/packages/svelte/messages/server-warnings/warnings.md +++ b/packages/svelte/messages/server-warnings/warnings.md @@ -2,7 +2,7 @@ > Assignment to derived state on the server is permanent and will not be recalculated when its dependencies change, unlike on the client where it is temporary -This warning is emitted when you reassign a value created with `$derived` while compiling with `generate: 'server'`. On the client such overrides are temporary and discarded once dependencies change; on the server the derived is memoized with `once(fn)` and the override is stored in a closure (`updated_value`), so it survives forever. See `sveltejs/svelte#18681` for details. +This warning is emitted when you reassign a value created with `$derived` or `$derived.by` while compiling with `generate: 'server'`. There is no reactivity on the server — derived values do not recompute when dependencies change, including overridden values. On the client, overrides are temporary and discarded when dependencies change. ## unresolved_hydratable