noSvelteUnnecessaryStateWrap
Summary
Section titled “Summary”- Rule available since:
v2.5.2 - Diagnostic Category:
lint/nursery/noSvelteUnnecessaryStateWrap - This rule has an unsafe fix.
- The default severity of this rule is information.
- This rule belongs to the following domains:
- Sources:
- Same as
svelte/no-unnecessary-state-wrap
- Same as
How to configure
Section titled “How to configure”{ "linter": { "rules": { "nursery": { "noSvelteUnnecessaryStateWrap": "error" } } }}Description
Section titled “Description”Disallow unnecessary $state wrapping of reactive classes.
Several classes exported from svelte/reactivity — such as SvelteMap, SvelteSet, and
SvelteDate — are already deeply reactive without the $state rune. Wrapping them in
$state(...) is redundant and may mislead readers into thinking the reactivity comes from
the rune rather than the class itself.
Use the additionalReactiveClasses option to extend this list with custom reactive classes
from your own codebase.
Use allowReassign: true if you need to reassign the variable itself after declaration,
which requires $state to track the reference change.
Examples
Section titled “Examples”Invalid
Section titled “Invalid”<script>import { SvelteMap } from "svelte/reactivity";const map = $state(new SvelteMap());</script>code-block.svelte:2:13 lint/nursery/noSvelteUnnecessaryStateWrap FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━
ℹ SvelteMap is already reactive, wrapping it in $state() is unnecessary.
1 │ import { SvelteMap } from “svelte/reactivity”;
> 2 │ const map = $state(new SvelteMap());
│ ^^^^^^^^^^^^^^^^^^^^^^^
3 │
ℹ Classes from svelte/reactivity track their own mutations without needing a $state wrapper.
ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.
ℹ Unsafe fix: Remove the unnecessary $state() wrapper.
2 │ const·map·=·$state(new·SvelteMap());
│ ------- -
<script>import { SvelteMap } from "svelte/reactivity";const map = new SvelteMap();</script>Options
Section titled “Options”allowReassign
Section titled “allowReassign”When true, suppresses the autofix for variables that are reassigned after declaration.
Because reassigning a $state-wrapped value changes the binding itself, removing $state
would break reactivity for those reassignments. The diagnostic still fires — only the
unsafe autofix is withheld.
Default: false
{ "linter": { "rules": { "nursery": { "noSvelteUnnecessaryStateWrap": { "level": "on", "options": { "allowReassign": true } } } } }}<script>import { SvelteMap } from "svelte/reactivity";const map = $state(new SvelteMap());</script>code-block.svelte:2:13 lint/nursery/noSvelteUnnecessaryStateWrap FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━
ℹ SvelteMap is already reactive, wrapping it in $state() is unnecessary.
1 │ import { SvelteMap } from “svelte/reactivity”;
> 2 │ const map = $state(new SvelteMap());
│ ^^^^^^^^^^^^^^^^^^^^^^^
3 │
ℹ Classes from svelte/reactivity track their own mutations without needing a $state wrapper.
ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.
ℹ Unsafe fix: Remove the unnecessary $state() wrapper.
2 │ const·map·=·$state(new·SvelteMap());
│ ------- -
<script>import { SvelteMap } from "svelte/reactivity";let map = $state(new SvelteMap());map = new SvelteMap();</script>code-block.svelte:2:11 lint/nursery/noSvelteUnnecessaryStateWrap ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ℹ SvelteMap is already reactive, wrapping it in $state() is unnecessary.
1 │ import { SvelteMap } from “svelte/reactivity”;
> 2 │ let map = $state(new SvelteMap());
│ ^^^^^^^^^^^^^^^^^^^^^^^
3 │ map = new SvelteMap();
4 │
ℹ Classes from svelte/reactivity track their own mutations without needing a $state wrapper.
ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.
additionalReactiveClasses
Section titled “additionalReactiveClasses”An array of additional class names to treat as already reactive (beyond the built-in
svelte/reactivity classes). Use this to extend the rule with custom reactive classes
from your own codebase.
{ "linter": { "rules": { "nursery": { "noSvelteUnnecessaryStateWrap": { "level": "on", "options": { "additionalReactiveClasses": [ "MyReactiveStore" ] } } } } }}Invalid
Section titled “Invalid”<script>const store = $state(new MyReactiveStore());</script>code-block.svelte:1:15 lint/nursery/noSvelteUnnecessaryStateWrap FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━
ℹ MyReactiveStore is already reactive, wrapping it in $state() is unnecessary.
> 1 │ const store = $state(new MyReactiveStore());
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 │
ℹ Classes from svelte/reactivity track their own mutations without needing a $state wrapper.
ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.
ℹ Unsafe fix: Remove the unnecessary $state() wrapper.
1 │ const·store·=·$state(new·MyReactiveStore());
│ ------- -
<script>const store = new MyReactiveStore();</script>Related links
Section titled “Related links”Copyright (c) 2023-present Biome Developers and Contributors.