08 - Specialized Runes ($inspect, $host)

These are niche runes for specific use cases — unlike the core runes (01-07) you'll use daily.

$inspect() — Debug Reactive State

$inspect() logs to the console whenever its dependencies change. It's a development-only tool — automatically removed in production builds.

Basic Usage

<script lang="ts">
let count = $state(0);

$inspect(count);  // logs: init 0, then update 1, update 2, etc.
</script>

<button onclick={() => count++}>{count}</button>

Multiple Values

<script lang="ts">
let x = $state(0);
let y = $state(0);

$inspect(x, y);  // logs whenever either x or y changes
</script>

With Label

Add a string label to identify what you're inspecting:

<script lang="ts">
let user = $state({ name: 'Alice', age: 25 });

$inspect('User state:', user);  // logs: "User state:" { name: "Alice", age: 25 }
</script>

Custom Callback with .with()

Use .with() for custom logic instead of default console logging:

<script lang="ts">
let count = $state(0);

$inspect(count).with((type, ...values) => {
  // type is "init" on first run, "update" on changes
  if (values[0] > 10) {
    console.warn('Count exceeded 10!');
  }
});
</script>

When to Use

  • Debugging why a value changes unexpectedly
  • Tracking how often a reactive value updates
  • Verifying derived values compute correctly
  • Don't leave in production code — it's stripped out, but keep code clean

$host() — Custom Elements (Web Components)

$host() gives you access to the host element when building Svelte components as web components (custom elements). Only works with <svelte:options customElement="..." />.

Basic Usage

<svelte:options customElement="my-component" />

<script lang="ts">
const host = $host();  // reference to the <my-component> DOM element

$effect(() => {
  host.style.color = 'red';  // style the host element directly
});
</script>

<p>Custom element content</p>

Dispatching Custom Events

Web components communicate with the outside world via custom events:

<svelte:options customElement="my-button" />

<script lang="ts">
const host = $host();

function handleClick() {
  host.dispatchEvent(new CustomEvent('custom-click', {
    detail: { timestamp: Date.now() }
  }));
}
</script>

<button onclick={handleClick}>Click</button>
<!-- Usage in plain HTML -->
<my-button></my-button>

<script>
  document.querySelector('my-button')
    .addEventListener('custom-click', (e) => {
      console.log('Clicked at:', e.detail.timestamp);
    });
</script>

When to Use

  • Building reusable widgets for non-Svelte apps
  • Embedding Svelte components in plain HTML, WordPress, etc.
  • Most Svelte/SvelteKit apps don't need $host() — it's for the web component use case

Key Points

  • $inspect() — dev-only debugging tool, removed in production
  • $inspect().with() — custom callback instead of console.log
  • $host() — access host element in custom elements only
  • Both are specialized runes for specific use cases, not everyday tools

Complete Example

<script lang="ts">
let count = $state(0);
let user = $state({ name: 'Alice', age: 25 });
let items = $state([1, 2, 3]);
let doubled = $derived(count * 2);

// Basic inspection
$inspect(count);

// Labeled inspection
$inspect('User:', user);

// Custom callback — warn when count gets high
$inspect(count).with((type, value) => {
  if (value > 5) console.warn('Count is getting high!');
  if (value > 10) console.error('Count exceeded 10!');
});

$inspect('Doubled:', doubled);
</script>

<div>
  <h1>Advanced Runes Demo</h1>
  <p>Open your browser console to see $inspect() logs</p>
  
  <section>
    <h3>Count: {count}</h3>
    <button onclick={() => count++}>Increment</button>
  </section>
  
  <section>
    <h3>User: {user.name}, Age: {user.age}</h3>
    <button onclick={() => user.age++}>Birthday</button>
  </section>
  
  <section>
    <h3>Items: {items.join(', ')}</h3>
    <button onclick={() => items.push(items.length + 1)}>Add Item</button>
  </section>
  
  <button onclick={() => { count = 0; user = { name: 'Alice', age: 25 }; items = [1, 2, 3]; }}>
    Reset All
  </button>
</div>