$props
The inputs to a component are referred to as props, which is short for properties. You pass props to components just like you pass attributes to elements:
<script>
import MyComponent from './MyComponent.svelte';
</script>
<MyComponent adjective="cool" />
On the other side, inside MyComponent.svelte
, we can receive props with the $props
rune...
<script>
let props = $props();
</script>
<p>this component is {props.adjective}</p>
...though more commonly, you’ll destructure your props:
<script>
let { adjective } = $props();
</script>
<p>this component is {adjective}</p>
Fallback values
Destructuring allows us to declare fallback values, which are used if the parent component does not set a given prop:
let { let adjective: any
adjective = 'happy' } = function $props(): any
Declares the props that a component accepts. Example:
let { optionalProp = 42, requiredProp, bindableProp = $bindable() }: { optionalProp?: number; requiredProps: string; bindableProp: boolean } = $props();
$props();
Fallback values are not turned into reactive state proxies.
Renaming props
We can also use the destructuring assignment to rename props, which is necessary if they’re invalid identifiers, or a JavaScript keyword like super
:
let { super: let trouper: any
trouper = 'lights are gonna find me' } = function $props(): any
Declares the props that a component accepts. Example:
let { optionalProp = 42, requiredProp, bindableProp = $bindable() }: { optionalProp?: number; requiredProps: string; bindableProp: boolean } = $props();
$props();
Rest props
Finally, we can use a rest property to get, well, the rest of the props:
let { let a: any
a, let b: any
b, let c: any
c, ...let others: any
others } = function $props(): any
Declares the props that a component accepts. Example:
let { optionalProp = 42, requiredProp, bindableProp = $bindable() }: { optionalProp?: number; requiredProps: string; bindableProp: boolean } = $props();
$props();
Updating props
References to a prop inside a component update when the prop itself updates — when count
changes in App.svelte
, it will also change inside Child.svelte
. But the child component is able to temporarily override the prop value, which can be useful for unsaved emphemeral state (demo):
<script>
import Child from './Child.svelte';
let count = $state(0);
</script>
<button onclick={() => (count += 1)}>
clicks (parent): {count}
</button>
<Child {count} />
<script>
let { count } = $props();
</script>
<button onclick={() => (count += 1)}>
clicks (child): {count}
</button>
Type safety
You can add type safety to your components by annotating your props, as you would with any other variable declaration. In TypeScript that might look like this...
<script lang="ts">
let { adjective }: { adjective: string } = $props();
</script>
...while in JSDoc you can do this:
<script>
/** @type {{ adjective: string }} */
let { adjective } = $props();
</script>
You can, of course, separate the type declaration from the annotation:
<script lang="ts">
interface Props {
adjective: string;
}
let { adjective }: Props = $props();
</script>
Adding types is recommended, as it ensures that people using your component can easily discover which props they should provide.