Reactive Logging
console.log doesn’t understand reactivity. It logs once and forgets. When you’re debugging why something re-rendered, you need something better.
$inspect is console.log for reactive state. It re-runs whenever the value changes, showing you exactly when updates happen.
Basic Usage
<script>
let count = $state(0);
$inspect(count);
</script>
<button onclick={() => count++}>Increment</button> Every time count changes, you’ll see it in the console:
init 0
update 1
update 2
update 3 The init happens when the component mounts. Each update is a change.
Inspecting Objects
For objects and arrays, $inspect shows the full value:
<script>
let user = $state({ name: 'Alice', score: 0 });
$inspect(user);
</script>
<button onclick={() => user.score++}>Add Point</button> init { name: 'Alice', score: 0 }
update { name: 'Alice', score: 1 }
update { name: 'Alice', score: 2 } Multiple Values
Inspect several values at once:
<script>
let firstName = $state('Ada');
let lastName = $state('Lovelace');
$inspect(firstName, lastName);
</script> init Ada Lovelace
update Augusta Lovelace Custom Handling with .with()
The default logs to console. Use .with() for custom behavior:
<script>
let data = $state({ x: 0, y: 0 });
$inspect(data).with((type, value) => {
if (type === 'update') {
console.log('Data changed:', JSON.stringify(value));
}
});
</script> The callback receives:
type: Either'init'or'update'value: The current value (or values, if you passed multiple)
Breakpoint on Change
Drop into the debugger when a value changes:
<script>
let count = $state(0);
$inspect(count).with((type, value) => {
if (type === 'update' && value > 10) {
debugger; // Pause here when count exceeds 10
}
});
</script> Trace to a File or Service
<script>
let formData = $state({ email: '', password: '' });
$inspect(formData).with((type, value) => {
// Don't log passwords in production!
if (import.meta.env.DEV) {
console.table(value);
}
});
</script> Debugging Derived Values
$inspect works with $derived too:
<script>
let items = $state([1, 2, 3]);
let total = $derived(items.reduce((a, b) => a + b, 0));
$inspect(total);
</script> Now you see when the derived value recalculates—useful for checking if expensive computations run more often than expected.
Remember to Remove
$inspect is for development. Remove it before production:
<script>
let count = $state(0);
// TODO: Remove before commit
$inspect(count);
</script> Or guard it:
<script>
let count = $state(0);
if (import.meta.env.DEV) {
$inspect(count);
}
</script> When to Use $inspect
- Unexpected re-renders: Is something updating more than it should?
- State not updating: Is the change actually happening?
- Timing issues: When exactly does this value change?
- Derived confusion: Is the derived value recalculating correctly?
For deeper reactive tracing, check $inspect.trace() in the Svelte docs. But for most debugging, basic $inspect is all you need.