Svelte has development tools to inspect state and find out why a reactive calculation runs again.
In this example, we'll watch our todos in the console.
$inspect logs initially and whenever its arguments change. It tracks deeply reactive properties too, so checking a todo logs an update.
TodoList.svelte
<script> let todos = $state([ { task: 'Walk dog', completed: false }, ]); $inspect(todos);</script>{#each todos as todo} <label> <input type="checkbox" bind:checked={todo.completed}> {todo.task} </label>{/each}
Tracing Updates
$inspect.trace must be the first statement in the function. When this derived calculation runs again, it logs which reactive reads caused the update.
TodoList.svelte
<script> let todos = $state([ { task: 'Walk dog', completed: false }, ]); let remaining = $derived.by(() => { $inspect.trace('Remaining todos'); return todos.filter((todo) => !todo.completed).length; });</script>{#each todos as todo} <label> <input type="checkbox" bind:checked={todo.completed}> {todo.task} </label>{/each}<p>{remaining} todos left</p>
Both $inspect and $inspect.trace only work during development. They do nothing in a production build. Tracing works in functions that run as part of a derived calculation or an effect.