Runes are the Svelte 5 reactivity primitives. $state creates a signal, $derived creates a lazy memoized computation, and $effect subscribes to whatever it reads, while the compiler turns each template expression into a direct DOM write with no virtual DOM in between.
In Svelte 4, reactivity was tied to assignment inside a component: the compiler instrumented every `x = ...` statement it could see. That worked inside a .svelte file and broke as soon as state moved into a plain module or a function. Runes replace that with explicit primitives that behave the same everywhere: $state, $derived and $effect are compiler keywords that expand into calls to a small signal runtime.
A $state value is a source signal: an object holding the current value, a version number, and a list of reactions that read it. $derived creates a derived signal that stays unevaluated until something reads it, then caches the result and records which sources it touched. $effect creates an effect that runs after the DOM has been updated and re-runs whenever one of its dependencies changes. Dependencies are never declared; they are collected by tracking reads while the function runs.
The graph is push-pull. A write to a source pushes a dirty flag along its recorded edges: deriveds that read it become dirty, and reactions of those deriveds become maybe-dirty, since a derived may recompute to an equal value. Nothing recomputes at write time. A microtask flush then runs the queued effects, and each effect pulls fresh values as it reads them, which is what finally recomputes a dirty derived. Equal results stop propagation early.
The other half is the compiler. Because markup is static, Svelte knows at build time that a given text node depends on a given expression. It emits a template string that is cloned into real DOM once, then a template effect per dynamic expression that calls set_text or set_attribute on the exact node it owns. There is no tree of virtual nodes to build on every update and no diff to find what changed, because the dependency between signal and node was resolved before the code ran.
Interview framing: define Svelte Runes in one sentence, then explain one concrete runtime behavior and one common pitfall with a short code example.