BB SKILLS / LEARN

Svelte 5 reactivity: props, keyed lists and browser evidence

Debug Svelte 5 reactivity with a version-pinned official skill: distinguish compiler diagnostics from browser behavior, test changing props and verify keyed DOM identity.

Choose an official snapshot that matches your project

Svelte provides separate skills for core practices and code-writing tools. This guide uses the official Svelte core practices resource, released on October 3, 2026 and pinned to commit 1a3ba88bba598c6734533c48e23cb5d37424b618. The download retains the original instruction file, all nine references and the complete MIT notice attributed to Svelte Contributors. All ten skill files match that official release archive byte for byte; the repository license is retained separately.

BB Skills adds a clearly marked preface, an independent synthetic fixture and its recorded results. These additions are not upstream certification. We tested Svelte 5.57.2 with Node 24.10.0 and esbuild 0.28.2 on Windows, in Chrome 154. The skill snapshot and tested compiler have separate version identities. Your own lockfile, compiler options and runtime remain the authority for your project.

The official skill overview explains the two resources. The code-writer CLI is outside this experiment; we did not execute its MCP tools, fetch remote documentation through an agent or run a complete skill in an AI client.

Read documentation contrasts before compiling them

A documentation block is not always a standalone component. The upstream derived-state and props blocks place a recommended form and a counterexample in the same block, redeclaring a variable. The event blocks contain placeholders. We wrapped the JavaScript contrasts in a synthetic script context and submitted each complete block unchanged. All four were rejected with js_parse_error, as expected.

That outcome does not make the recommendations invalid. It means a reader should choose the relevant example and supply the missing context before using it in an application. Our fixture records the exact block hash, wrapper and diagnostic. It does not silently fix an example and report the rewritten version as an unchanged upstream success.

Four other complete blocks compile for both client and server: the greeting snippet, CSS custom-property directive, keyed each example and function binding. The latter three receive synthetic declarations or props around the unchanged original block. For compiler options and diagnostic types, use the Svelte compiler documentation.

Assert the change, not only the first render

The independently authored component starts with number = 2 and square = $derived(number * number). After an event increments the number to 3, the rendered square becomes 9. A local assignment temporarily overrides the derived value to 99; changing its dependency again replaces that override with 16. These are recorded DOM observations for this installed version, not a promise about every older Svelte release.

Controlled changeObserved DOM resultDebugging implication
Mutate a nested value in a $state objectThe displayed value changes from 1 to 2.Deep reactive state can observe this mutation.
Mutate a nested value in a $state.raw objectThe displayed value remains 1 at that observation.Use reassignment when relying on raw state updates.
Reassign the raw objectThe displayed value becomes 7.Assert the actual reassignment path.
Change a child prop from safe to dangerThe $derived color changes from green to red.Prop-dependent computed values should follow their input.
Make the same prop change with a plain initialized variableThe deliberately frozen color stays green.A correct initial render can conceal a stale value.

The frozen-prop component also produces a state_referenced_locally compiler warning. The browser confirms the stale result independently. A warning identifies a suspicious source pattern; the DOM assertion establishes the behavior of this specific example. Keep both kinds of evidence rather than replacing one with the other.

Check keyed node identity without inventing a speed claim

The unchanged reference contains two keyed loops, each using item.id. Synthetic items Alpha, Beta and Gamma produce six list entries. Reordering the items moves the existing Gamma node to the first position in each loop. We compare the actual DOM objects before and after the change, not only their visible text. Removing Alpha deletes its two entries while the retained Gamma node survives.

Stable, unique keys express item identity. An array index changes its meaning when items move. The fixture uses unique string IDs and checks reorder and removal; it does not benchmark rendering speed, test duplicate-key failures or cover every component-local state interaction. If the bug involves a nested component, input focus or animation, add an assertion for that specific behavior in your application.

Test bindings and CSS at the boundary

The original function-binding block lowercases an entered value. Our synthetic browser experiment sets the input to MiXeD and dispatches an input event; the output becomes mixed. This verifies the transformation in the real DOM. It is a programmatic event, so it does not establish trusted-input behavior, IME handling, autofill or accessible keyboard interaction.

The unchanged style:--columns example receives a synthetic prop. Its DOM style property starts at 2 and changes to 4 after the prop changes. We inspect the custom property directly. The example does not include a grid layout, so this result is not a visual layout or paint-performance test.

The original greeting snippet renders hello world! in both the server output and browser. Snippet reuse, input transformation and style updates each need their own assertion; a successful compile alone does not prove any of those visible results.

Keep compiler, server and browser evidence separate

Evidence layerRecorded scopeRemaining work
15 compiler and server observationsFour intentional block rejections, eight client/server compilations, two server-render observations and one frozen-prop warning.Type checking, complete projects, build integrations and other compiler versions.
23 Chrome DOM observationsGreeting, derived state, deep/raw updates, changing props, keyed node identity, function binding, CSS property and a browser effect.Trusted user input, accessibility, layout, hydration, concurrency and browser comparisons.
Independent effect counterexampleThe synthetic effect output is 0 during server render and 1 in the browser.Production side effects and request isolation.
Source and licensing reviewFixed commit, official release bytes, nine local references and retained MIT notices.Upstream endorsement or complete AI-client skill execution.

The local server binds only to 127.0.0.1. Its page loads no external resource and uses synthetic data. No account, database, production route or paid API is involved. The package records runtime_tested: false for the complete skill. In particular, this experiment does not verify SvelteKit routing, asynchronous hydration, attachments, context isolation across real users or comprehensive security.

Reproduce the local experiment

Extract the download and work from its svelte-core-bestpractices directory. Use a compatible Node installation and the included lockfile. Dependency installation contacts the free public npm registry; downloaded dependencies and runtime binaries are not bundled in the skill archive. Installation scripts are disabled in this recorded workflow.

npm ci --ignore-scripts --no-audit --no-fund
node examples/build_fixture.mjs
node examples/serve_fixture.mjs

Open http://127.0.0.1:5851/ in your normal browser and click Run local observations once on a fresh page. Inspect the displayed record, then stop the local server. Reload before another run because the checks intentionally change state and list contents. The builder writes a new compiler evidence record with your versions and time; the included browser evidence is the historical run, not a claim about your machine.

The generated component files are teaching fixtures. One child intentionally preserves a stale prop value to demonstrate the failure. Do not copy that counterexample into production. Use the source hashes and named observations to understand precisely which example a result belongs to.

Choose the next test for your task

Use the Svelte core practices skill for framework-specific decisions. For project tests, the Vitest workflow can help organize assertions and fixtures. The Playwright CLI browser workflow covers browser evidence and persistent-profile boundaries. The persistent-browser guide explains how to distinguish local inspection from a complete AI task run.

If the task starts with interface design, consult Frontend Design, then verify the interaction with the installed framework. If it involves permissions, untrusted HTML or private data, use the evidence-based security review and application-specific tests. A reactive UI result does not prove authorization or safe content handling.

This guide was prepared with AI assistance and independently executed local fixtures on October 8, 2026. The pinned upstream source, original files and separately labeled evidence support the claims above. There is no fabricated reviewer identity, endorsement, performance score or full-skill certification.

Resources in this guide

Open the library →