Passing Data with Props

+15 Mana ✨

Components become truly powerful when they can receive data from their parent. In Svelte 5, we use the $props rune to declare what data a component accepts.

Declaring Props

svelte
<!-- Greeting.svelte -->
<script>
  let { name } = $props();
</script>

<h1>Hello, {name}!</h1>

$props() returns an object containing all the props passed to this component. We destructure it to get the values we need.

Passing Props

Pass props just like HTML attributes:

svelte
<!-- App.svelte -->
<script>
  import Greeting from './Greeting.svelte';
</script>

<Greeting name="Alice" />
<Greeting name="Bob" />

Default Values

Provide defaults using JavaScript's default parameter syntax:

svelte
<script>
  let { 
    name = 'World',     // Default: 'World'
    age = 18,           // Default: 18
    isActive = false    // Default: false
  } = $props();
</script>

<p>{name} is {age} years old</p>

Multiple Props

svelte
<!-- UserCard.svelte -->
<script>
  let { 
    name,
    email,
    avatar = '/default-avatar.png',
    role = 'user'
  } = $props();
</script>

<div class="card">
  <img src={avatar} alt={name} />
  <h2>{name}</h2>
  <p>{email}</p>
  <span class="badge">{role}</span>
</div>

Rest Props

Capture remaining props with the spread operator:

svelte
<!-- Button.svelte -->
<script>
  let { children, variant = 'primary', ...rest } = $props();
</script>

<!-- All extra props (like id, class, onclick) are passed to the button -->
<button class="btn btn-{variant}" {...rest}>
  {@render children()}
</button>

Now you can use it like:

svelte
<Button id="submit-btn" class="large" onclick={handleSubmit}>
  Submit
</Button>

Dynamic Props

Pass reactive values as props:

svelte
<script>
  import Counter from './Counter.svelte';
  
  let startValue = $state(10);
</script>

<input type="number" bind:value={startValue} />
<Counter initial={startValue} />
✓ Completed