feat(no-unnecessary-state-wrap): support string array in allowReassign
, default to true
and improve messages
chore: add windows CI
#1122 Mar 10, 2025feat: Add svelte/valid-context-access
rule
New rule: svelte/prefer-derived-over-derived-by
$derived.by
. There is no performance difference. It purely enforces a consistent coding style. Even if included in recommended config, a warning level should be sufficient.
Description
This rule reports unnecessary usage of $derived.by
. It also provides a fixer to automatically convert $derived.by
to $derived
.
Examples
<script>
// ✓ GOOD
const foo = $derived(a.b);
// ✗ BAD
const bar = $derived.by(() => a.b);
</script>
Additional comments
No responsenew rule: prefer-attachments
prefer-sveltekit-response-helpers
error
and redirect
over using Response
. There might be some advanced cases where Response
is required, but it shouldn't be for simple ones
Examples
<!-- ✓ GOOD -->
redirect(307, "/");
<!-- ✗ BAD -->
return new Response(null, {
status: 307,
headers: {
Location: "/"
}
});
Additional comments
No responsedisallow-reactive-vars-on-mount
#1205 Apr 24, 2025<script>
import { onMount } from 'svelte';
let count = $state(0);
// ✗ BAD
onMount(() => {
console.log(count);
});
</script>
<!-- ✓ GOOD -->
{#if count > 0}
<p>Count is positive</p>
{/if}
Additional comments
No responseno-unnecessary-state-wrap triggers too often
#1154 Apr 19, 2025eslint-plugin-svelte
are you using?
3.3.3
What did you do?
Tried to upgrade https://github.com/immich-app/immich/tree/main/web to 3.3.3
It triggered no-unnecessary-state-wrap
in two places. One was helpful, but the other I consider to be a false positive
What did you expect to happen?
This shouldn't be $state
and should be a const
: https://github.com/immich-app/immich/blob/392ce7deb2683d2c66a821c617329b3641491016/web/src/lib/components/forms/tag-asset-form.svelte#L21
However, this one is pretty reasonable because you're creating a new SvelteSet
and it's a lot more cumbersome to clear
the set and then add
each item: https://github.com/immich-app/immich/blob/90f21d9047aa33dcb8231ab61269e60a32aedd9f/web/src/lib/components/utilities-page/duplicates/duplicates-compare-control.svelte#L86
I think we should trigger the rule only when the variable is not being reassigned
What actually happened?
It said that I should not use $state
in either location.
Link to GitHub Repo with Minimal Reproducible Example
The full repo is here: https://github.com/immich-app/immich/tree/main/web
I can create a smaller version if needed
Additional comments
No response⚠️ Read this about TS parsing errors before submitting an issue ⚠️
#1111 Apr 10, 2025eslint.config.js
.
Please refer to the documentation and ensure your settings are correct. If the error persists despite correct configuration, feel free to open an issue.
https://github.com/sveltejs/eslint-plugin-svelte?tab=readme-ov-file#typescript-projectnew rule: no-nested-style-tag
<script>
</script>
<!-- ✓ GOOD -->
<style>...</style>
<!-- ✗ BAD -->
<div>
<style>...</style>
</div>
{@snippet}
<style>...</style>
{/snippet}
Additional comments
No responseNew Rule: svelte/kit-parent-function-at-bottom rule
#438 Jan 3, 2025parent
.
/** @type {import('./$types').PageLoad} */
export async function load({ params, parent }) {
const parentData = await parent();
// ^ `parent` function can execute later to avoid a waterfall
const data = await getData(params);
return {
...data
meta: { ...parentData.meta, ...data.meta }
};
}
Description
SvelteKit has parent
function. And according to the document, parent
should use at the bottom of load
function as much as possible in terms of performance.
https://kit.svelte.dev/docs/load#using-parent-data
But it's too difficult to recognize by human code review, so I would like to recognize this automatically.
Examples
/** @type {import('./$types').PageLoad} */
export async function load({ params, parent }) {
// NG
const parentData = await parent();
const data = await getData(params);
// OK
const parentData = await parent();
// OK (Because `doSomething` needs to use the return value of `parent`.)
const foo = await doSomething(parentData);
return {
...data
meta: { ...parentData.meta, ...data.meta }
};
}
Additional comments
I need to think about better rule name.😅New Rule: svelte/valid-context-access
getContext
needs to call during component initialization.
Svelte team tried to implement this in the compiler, but this is a bit difficult, so I thought that we will implement this as ESLint rule.
https://svelte.dev/docs#run-time-svelte-getcontext
Retrieves the context that belongs to the closest parent component with the specified key. Must be called during component initialisation.
Examples
<script>
import { getContext } from 'svelte';
let test = getContext('test');
</script>
<!-- ✓ GOOD -->
<a href={test}>xxx</a>
<!-- ✗ BAD -->
<a href={getContext('test')}>xxx</a>
Additional comments
No responseSvelte5: Add svelte/no-getter-setter
rule
Svelte5: Add svelte/no-string-event-attribute
Migrate the docs to Svelte 5
#754 Jan 2, 2025Svelte5: Add svelte/no-legacy-svelte-ignore
rule
svelte-ignore
still works for the previous kebab-case error codes.
However, I expect support for the old format will be removed eventually.
The new rule help with this migration.
Description
The new rule disallow svelte-ignore using old-style error codes.
Note, however, that they will only be reported if you are using Svelte v5 or later.
Examples
<!-- ✓ GOOD -->
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
<span tabindex="0">
<span class="element"></span>
</span>
<div>
<!-- svelte-ignore block_empty -->
{#await Promise.resolve(foo)}
{/await}
</div>
<!-- ✗ BAD -->
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
<span tabindex="0">
<span class="element"></span>
</span>
<div>
<!-- svelte-ignore empty-block -->
{#await Promise.resolve(foo)}
{/await}
</div>
Additional comments
No responseNew Rule: invalid-attribute
onclick
attribute like i asked months ago (well now it would actually be the opposite ironically) or something more general for some specific reasons i think having a way to specify a list of invalid attributes could be a good rule to have.
Description
The user can provide through rule options a list of invalid attributes/regex. Every component using such attribute will be reported.
Examples
Given a configuration like this
{
"rules": {
"svelte/invalid-attribute": ["error", ["title"]]
}
}
<!-- ✗ BAD -->
<Foo title=""/>
<Foo {title}/>
<Foo bind:title/>
<Foo title={somevar}/>
we probably can also error on props named that way for in-repo components.
Additional comments
I got a very barebone version of this already and if interested i can work on it and submit a PR.Svelte5: Add svelte/no-store
rule
Optionally use alphabetic ordering if numeric ordering is not present
#825 Jul 13, 2024Publishing docs on svelte.dev or highlighting them there
#824 Jul 12, 2024Apply @typescript-eslint/no-misused-promises
to Svelte components
const promiseFunc: () => Promise<void> = async () => {};
// pnpm lint will identify this as an issue as it should
const func: () => void = promiseFunc;
But if I do the same thing with a Svelte component property I can't get it to detect it.
Examples
<!-- file: Child.svelte -->
<script lang="ts">
export let func: () => void;
func();
</script>
<!-- file: +page.svelte -->
<script lang="ts">
import Child from './Child.svelte';
const promiseFunc: () => Promise<void> = async () => {};
</script>
<!-- ✗ BAD -->
<Child func={promiseFunc} />
Additional comments
I don't know if this should be considered a new rule or just apply @typescript-eslint/no-misused-promises
somehow.
See here for an example of the existing eslint rule and what I'd like eslint-plugin-svelte
to catch: https://github.com/benmccann/promise-linting/blob/master/src/routes/%2Bpage.svelte
I hit this issue a lot while trying to migrate a large project to Svelte 5 where I was replacing components events with component callback props and it became very hard to keep track of what should be asynchronous vs synchronous: https://github.com/immich-app/immich/pull/7187#discussion_r1504663631