# $props — Svelte / SvelteKit

Source: https://www.skillbyai.com/en/svelte/c-props

> Typed inputs with defaults.

## Destructuring props

A component reads its inputs with `let { title, count = 0, ...rest } = $props()`. Defaults apply when the parent passes `undefined`; the rest pattern collects remaining attributes, which you can spread onto an element with `{...rest}`. Props update when the parent changes them. With TypeScript, describe them with an interface and annotate the destructuring: `let { title }: Props = $props()`. You can extend element attribute types such as `HTMLButtonAttributes` from `svelte/elements`. Treat props as read-only unless they are bindable. Svelte 4 used `export let title;` and `$$restProps`.

## Data down, callbacks and snippets in

Components receive props, report changes through callbacks or bindings, and accept markup as snippets.

![Three ideas: $props, events and $bindable, snippets and {@render}.](assets/figures/svelte/section-3-map.svg) — Figure 3.1 — Parent passes props and snippets; child calls back or binds.

## A typed Button component

Defaults, rest props and spread.

```svelte
<!-- Button.svelte -->
<script lang="ts">
  import type { HTMLButtonAttributes } from 'svelte/elements';

  interface Props extends HTMLButtonAttributes {
    variant?: 'primary' | 'ghost';
    label: string;
  }

  let { variant = 'primary', label, ...rest }: Props = $props();
</script>

<button class={variant} {...rest}>{label}</button>

<!-- Usage in a parent:
<Button label="Save" type="submit" />
<Button label="Cancel" variant="ghost" onclick={close} />
-->
```

## Use $props.id for accessible ids

Svelte 5 provides $props.id() to generate an id unique to the component instance and stable between server and client, useful for label and aria attributes. Check the docs for your version.

**Quiz:** How does a Svelte 5 component declare a prop with a default value?

- [x] let { size = 16 } = $props();
- [ ] export let size = 16;
- [ ] const size = $state.prop(16);
- [ ] props.size ||= 16;

*Answer:* let { size = 16 } = $props();. Svelte 4 used export let; Svelte 5 uses $props.
