diff --git a/apps/svelte.dev/content/docs/svelte/01-introduction/03-svelte-files.md b/apps/svelte.dev/content/docs/svelte/01-introduction/03-svelte-files.md
index f534e30fcb..e3dd72c222 100644
--- a/apps/svelte.dev/content/docs/svelte/01-introduction/03-svelte-files.md
+++ b/apps/svelte.dev/content/docs/svelte/01-introduction/03-svelte-files.md
@@ -50,6 +50,9 @@ A `
+
+
+```
+
+Because Svelte's legacy mode reactivity is based on _assignments_, using array methods like `.push()` and `.splice()` won't automatically trigger updates. A subsequent assignment is required to 'tell' the compiler to update the UI:
+
+```svelte
+
+```
diff --git a/apps/svelte.dev/content/docs/svelte/99-legacy/02-legacy-reactive-assignments.md b/apps/svelte.dev/content/docs/svelte/99-legacy/02-legacy-reactive-assignments.md
new file mode 100644
index 0000000000..5f7c9da790
--- /dev/null
+++ b/apps/svelte.dev/content/docs/svelte/99-legacy/02-legacy-reactive-assignments.md
@@ -0,0 +1,87 @@
+---
+title: Reactive $: statements
+---
+
+In runes mode, reactions to state updates are handled with the [`$derived`]($derived) and [`$effect`]($effect) runes.
+
+In legacy mode, any top-level statement (i.e. not inside a block or a function) can be made reactive by prefixing it with a `$:` [label](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/label). These statements run after other code in the `
+```
+
+Statements are ordered _topologically_ by their dependencies and their assignments: since the `console.log` statement depends on `sum`, `sum` is calculated first even though it appears later in the source.
+
+Multiple statements can be combined by putting them in a block:
+
+```js
+// @noErrors
+$: {
+ // recalculate `total` when `items` changes
+ total = 0;
+
+ for (const item of items) {
+ total += item.value;
+ }
+}
+```
+
+The left-hand side of a reactive assignments can be an identifier, or it can be a destructuring assignment:
+
+```js
+// @noErrors
+$: ({ larry, moe, curly } = stooges);
+```
+
+## Understanding dependencies
+
+The dependencies of a `$:` statement are determined at compile time — they are whichever variables are referenced (but not assigned to) inside the statement.
+
+In other words, a statement like this will _not_ re-run when `count` changes, because the compiler cannot 'see' the dependency:
+
+```js
+// @noErrors
+let count = 0;
+let double = () => count * 2;
+
+$: doubled = double();
+```
+
+Similarly, topological ordering will fail if dependencies are referenced indirectly: `z` will never update, because `y` is not considered 'dirty' when the update occurs. Moving `$: z = y` below `$: setY(x)` will fix it:
+
+```svelte
+
+```
+
+## Browser-only code
+
+Reactive statements run during server-side rendering as well as in the browser. This means that any code that should only run in the browser must be wrapped in an `if` block:
+
+```js
+// @noErrors
+$: if (browser) {
+ document.title = title;
+}
+```
diff --git a/apps/svelte.dev/content/docs/svelte/99-legacy/03-legacy-export-let.md b/apps/svelte.dev/content/docs/svelte/99-legacy/03-legacy-export-let.md
new file mode 100644
index 0000000000..877e105b1f
--- /dev/null
+++ b/apps/svelte.dev/content/docs/svelte/99-legacy/03-legacy-export-let.md
@@ -0,0 +1,72 @@
+---
+title: export let
+---
+
+In runes mode, [component props](basic-markup#Component-props) are declared with the [`$props`]($props) rune, allowing parent components to pass in data.
+
+In legacy mode, props are marked with the `export` keyword, and can have a default value:
+
+```svelte
+
+```
+
+The default value is used if it would otherwise be `undefined` when the component is created.
+
+> [!NOTE] Unlike in runes mode, if the parent component changes a prop from a defined value to `undefined`, it does not revert to the initial value.
+
+Props without default values are considered _required_, and Svelte will print a warning during development if no value is provided, which you can squelch by specifying `undefined` as the default value:
+
+```js
+export let foo +++= undefined;+++
+```
+
+## Component exports
+
+An exported `const`, `class` or `function` declaration is _not_ considered a prop — instead, it becomes part of the component's API:
+
+```svelte
+
+
+```
+
+```svelte
+
+
+
+
+
+
+```
+
+## Renaming props
+
+The `export` keyword can appear separately from the declaration. This is useful for renaming props, for example in the case of a reserved word:
+
+```svelte
+
+
+```
diff --git a/apps/svelte.dev/content/docs/svelte/99-legacy/04-legacy-$$props-and-$$restProps.md b/apps/svelte.dev/content/docs/svelte/99-legacy/04-legacy-$$props-and-$$restProps.md
new file mode 100644
index 0000000000..33cac97035
--- /dev/null
+++ b/apps/svelte.dev/content/docs/svelte/99-legacy/04-legacy-$$props-and-$$restProps.md
@@ -0,0 +1,30 @@
+---
+title: $$props and $$restProps
+---
+
+In runes mode, getting an object containing all the props that were passed in is easy, using the [`$props`]($props) rune.
+
+In legacy mode, we use `$$props` and `$$restProps`:
+
+- `$$props` contains all the props that were passed in, including ones that are not individually declared with the `export` keyword
+- `$$restProps` contains all the props that were passed in _except_ the ones that were individually declared
+
+For example, a `