Let's explore advanced patterns for working with component props.

Destructuring with Defaults

svelte
<script>
  let {
    // Required props (no default)
    id,
    label,
    
    // Optional props with defaults
    variant = 'primary',
    size = 'medium',
    disabled = false,
    
    // Callback props
    onclick = () => {},
    
    // Rest props for pass-through
    ...rest
  } = $props();
</script>

The Rest Pattern

Capture "everything else" with rest props:

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

<button class="btn btn-{variant}" {...rest}>
  {@render children()}
</button>

Usage:

svelte
<Button 
  variant="danger" 
  disabled 
  aria-label="Delete item"
  onclick={handleDelete}
>
  Delete
</Button>

All extra props (disabled, aria-label, onclick) are spread onto <button>.

TypeScript Props

svelte
<script lang="ts">
  type ButtonVariant = 'primary' | 'secondary' | 'danger';
  type ButtonSize = 'small' | 'medium' | 'large';
  
  interface Props {
    label: string;
    variant?: ButtonVariant;
    size?: ButtonSize;
    disabled?: boolean;
    onclick?: () => void;
  }
  
  let {
    label,
    variant = 'primary',
    size = 'medium',
    disabled = false,
    onclick
  }: Props = $props();
</script>

Renaming Props

Use aliasing when prop names conflict with reserved words:

svelte
<script>
  let { 
    class: className = '',  // Rename 'class' to 'className'
    for: htmlFor            // Rename 'for' to 'htmlFor'
  } = $props();
</script>

<div class={className}>
  <label for={htmlFor}>...</label>
</div>

Reactive Props

Props are reactive by default — changes from parent update the child:

svelte
<script>
  let { count } = $props();
  
  // This is DERIVED from the prop
  let doubled = $derived(count * 2);
</script>

<p>Count: {count}, Doubled: {doubled}</p>

$props vs $state for Local Copies

If you need to modify a prop locally without affecting the parent:

svelte
<script>
  let { initialValue = 0 } = $props();
  
  // Create local state initialized from prop
  let localValue = $state(initialValue);
</script>
✓ Completed