Skip to content

[Svelte 5] Mutating non-bound props lead to undefined behavior ($binds rune proposal) #9997

@GauBen

Description

@GauBen

Describe the bug

Given a parent:

<Child {value} />

And a child that can mutate its value prop:

<script>
	let {value} = $props()
	$inspect(value)
</script>

<input bind:value />

Updating the value in the child will skip $inspect but will properly update value (see reproduction)

The documentation reads

Props cannot be mutated, unless the parent component uses bind:. During development, attempts to mutate props will result in an error.

The behavior described above is not raising an error during development. However, I believe this should be enforced at compile time. Mutations have always created undefined behaviors in Svelte (mutations are always possible but not reactive) and it should be possible to solve it in Svelte 5 by forcing either immutability or bindings:

<script>
	const {size} = $props() // Cannot use `let` to declare props
	let {value} = $binds() // New rune idea
</script>

<input bind:value {size} />

Writing <Child {value} {size} /> would cause a "value must be bound" error

In the case of objects, I guess we could step a bit away from usual js where props are always mutable:

const { obj } = $props()
// This would work in js but should not compile in svelte
obj.prop = 1
// Compile error: cannot update `obj` as it is a constant prop

Reproduction

https://svelte-5-preview.vercel.app/#H4sIAAAAAAAACo2QT2uEMBDFv8o0LKjgn3tQYdtTocfemh7cOFsDMQlJtCzid2-M7Zaye-glMHlv3sz8FnIWEh2hbwtR3YiEkqMxJCf-YrbCzSg9htrpyfLtp3bcCuNbppgXo9HWw7Myk4ez1SMkZRWrcm9MNpdED3MnJ4QGDs53HtMkyZiqq98oVZv2RfNOQjRQqEUMPQnV0725auvKtNH5NAjZB88-eIn6ejUEy0NRMPU6CAefQko44dDNCFxbi9zLC40pj3pSPfA_WXfmFUV4AoFR9-IssCfU2zAuvwKLnf9FtsH4WTjgMFYbl2abchDKmbBeGtUbPjc8tIpfzZJm0LThOOW0xFLqj5SRb5GRfEefrdXdK97XL6KIi9ECAgAA

Logs

No response

System Info

svelte 5-rc.26

Severity

annoyance

Edit: merry Christmas! 🎅

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions