Repository: sveltejs/eslint-plugin-svelte
Pull request #1064 (2025-02-09 12:21:51)

feat: add `excludedRunes` option to the `prefer-const` rule
close part of https://github.com/sveltejs/eslint-plugin-svelte/issues/818

As explained here, `$state` also needs to be excluded from the `prefer-const` rule.
https://github.com/sveltejs/eslint-plugin-svelte/pull/985#issuecomment-2566907151

changeset-bot[bot]: ###  🦋  Changeset detected

Latest commit: 15e00383cef5f1922767f10e517f407b86f2a93a

**The changes in this PR will be included in the next version bump.**

<details><summary>This PR includes changesets to release 1 package</summary>

  | Name                 | Type  |
| -------------------- | ----- |
| eslint-plugin-svelte | Patch |

</details>

Not sure what this means? [Click here  to learn what changesets are](https://github.com/changesets/changesets/blob/main/docs/adding-a-changeset.md).

[Click here if you're a maintainer who wants to add another changeset to this PR](https://github.com/sveltejs/eslint-plugin-svelte/new/fix/prefer-const?filename=.changeset/flat-berries-carry.md&value=---%0A%22eslint-plugin-svelte%22%3A%20patch%0A---%0A%0Afix%3A%20ignore%20%60%24state%60%20in%20the%20%60prefer-const%60%20rule%0A)


github-actions[bot]: <!-- posted by pkg.pr.new-comment.mjs -->

## Try the Instant Preview in Online Playground

[ESLint Online Playground](https://eslint-online-playground.netlify.app/?overrideDeps=%7B%22eslint-plugin-svelte%22%3A%22https%3A%2F%2Fpkg.pr.new%2Feslint-plugin-svelte%401064%22%7D#eslint-plugin-svelte%20with%20typescript)

## Install the Instant Preview to Your Local

```
npm i https://pkg.pr.new/eslint-plugin-svelte@1064
```

## Published Instant Preview Packages:

- eslint-plugin-svelte: https://pkg.pr.new/eslint-plugin-svelte@1064

[View Commit](https://github.com/sveltejs/eslint-plugin-svelte/commit/15e00383cef5f1922767f10e517f407b86f2a93a)
ota-meshi: I still don't understand why you want to ignore `$state` from `svelte/prefer-const` rule.

I know that some users want to use `let` to change `value` with `const value = $state({ value: new Date().toString() });`, but I think that user would do the same with `const value = { value: new Date().toString() };` which doesn't use `$state()`. In other words, I think that user would always turn off the `prefer-const` rule.
So I don't think there's a need to ignore `$state` from the `svelte/prefer-const` rule check.
baseballyama: We might want to enable `prefer-const` for plain JavaScript that has nothing to do with Svelte.

In other words, semantically, since `$state` is something that can be reassigned, we may want to consistently use `let` for it. However, it’s understandable that some users would prefer to use `prefer-const` for regular JavaScript outside of that.

(Personally, I always use const consistently, though.😅)
baseballyama: In this case, there is no actual reassignment, so `prefer-const` would allow it to be declared as `const`. However, semantically, some people may prefer to declare it with `let`.

```js
export const Time3 = () => {
	// If `$state` has object value,
	// Time3 user cn reassign `value.value` even without reassign logic in this composable.
	// Therefore it can be declare as both `const` / `let`
	const value = $state( { value: new Date().toString() });

	return {
		get value() {
			return value;
		}
	}
}
```
baseballyama: Therefore, I am considering creating a separate rule, `prefer-let`. This rule will enforce the consistent use of `let`.
baseballyama: @ota-meshi So, what you’re saying is that extending `prefer-const` in the first place is unnecessary?
ota-meshi: > So, what you’re saying is that extending prefer-const in the first place is unnecessary?

No, I think `svelte/prefer-const` is necessary.
I don't think there's any need to ignore `$state()` from the `svelte/prefer-const` rule check.

Since we don't ignore `svelte/prefer-const` rule checks for mutable objects regardless of `$state()`, I think the rules would be inconsistent if we were to ignore only `$state()` from `svelte/prefer-const` rule checks.

If a primitive value of `$state()` is reported with `prefer-const`, it's just a case of the user using it incorrectly, and I think we can follow it with a different rule (e.g. `prefer-let`).


baseballyama: > If a primitive value of $state() is reported with prefer-const, it's just a case of the user using it incorrectly, and I think we can follow it with a different rule (e.g. prefer-let).

I still don’t fully understand this part. Since `$state` can hold non-primitive values such as object, are there cases where there is no direct reassignment? In such cases, is it correct for `const` to be enforced? Even if a `prefer-let` rule were implemented, wouldn’t it conflict with `prefer-const`, which enforces `const`?

https://svelte.dev/playground/hello-world?version=5.19.9#H4sIAAAAAAAAE32MzQqDMBAGX2VZCiqIlh6DFXrrO9Qeom4lkMaQrLZFfPcSpT-H0tsy38xOaOSVUOCRtO7h1jvdQkytYmoTTPGiNHkUpwn5YYMXAKav6mBt5kfSHFgtPf3iTW-YDHsUWPjGKctlZSrWxDB4crCHjWfJFMMEoRcQSa0ailKQHQnYbWGGpDJF_qlNYcvVncKPLNxzkdtyWZZsHWT35srYgaFWphWj1APtv1LI_xjhxyJgikx3RsFuoPk8PwFxCBbbPgEAAA==
ota-meshi: If in that example, `user` should be declared with `let`, then I think `user` should also be declared with `let` in the following source code.
What do you think?

https://eslint-online-playground.netlify.app/#eNq1VNuO0zAQ/RXLQtq2apMCb9nuConLG4J3AlJIJpVL4li2U3VV9d8Z3xK3CQsS2j7U8cw5x3Ozz1TJMv389L5rRceB60QdodFAM7pTpWRCP+ackAY04UUL5IG8UrrQsLgrGlbC3TJ4i33kfLNFe66NvVcg0XE2OEL2XmexDBZCJOhecmt2psvarSqAj0XTQ8TwkVjzNcXoYyQz8midqhvorbhLJNY2C/7t0qEguBGPJoqMnE2Cifm+7FKBPvSgRHDgZ7AzLnpNfjJeZVb9IaKS9BmE0bAAuqagGoZNKjtes31yUNgnhp2TmhwUqWXXkpy+c6D0oHJ6n3Pvd3392vR7xgPSATfCGjcOMcMppGmi5zjbJlCtL+Zo5VwBr58EuMJ5jgXDyYIrqIu+GUk+sYUp+UH5nUoklF3bAq+gst1LkuSGMYuJUw64bzmtm0KnETyn3y3Dj0DNGlAZQeBqla68SE7XmMu4cwwc/YLve2zQF6FZx5E2zJGrTHZVQ08KzilppEUmguXJTF8npUxD+Qfhcb7ND05aFp8wn48nDVy5wzCxSRojLayyt1UYwgiNT4WEGuQGy6mwlSYukLLDGOLb8td6Yv+uS2oNL17VYWqcYZr9P0ZvrtZV9MbwX9EPJy/v8ZqLovyFCijbcbziVsBdJVfytquwP77vOa3g+AGEGWZeMsBQhjOvXwNDxeEH0zl/bngEnnXevhAG+uNtsk22m20Ejt0Tpfl3wyq9niiNk/4HtZlXJcb5J/tCL78B2OY91w==
ota-meshi: The area I have an issue with is the consistency of the rule.
baseballyama: I fully understand your perspective.👍

As stated in the documentation, Svelte runes recommend using `let`. Based on my understanding, some users interpret JavaScript rules as being overridden by Svelte rules.
https://svelte.dev/docs/svelte/$state

In your example, since user does not use runes, I understood that standard JavaScript rules apply (without being overridden by Svelte rules). Therefore, I believed that the behavior of this PR was consistent.

Additionally, based on your reasoning, shouldn’t `$props` and `$derived` also consistently use const whenever possible? (I may not yet fully understand this part.)
ota-meshi: I think the reason why `$derived` should be `let` is because it is changed from outside.
But `$state` doesn't really fit that reason.
For primitive values, the user should assign it somewhere, so it won't be reported to `prefer-const`.
If the reason to use `let` is that the object is mutable, then I think objects with `setters` should use `let`.

>  Svelte runes recommend using `let`.

Hmm... I don't think it explicitly says "recommended". I think it's still a matter of user preference 🤔 
baseballyama: I see. Would adding a config be a good middle ground? Like `{ enforceState: false }`?
I want to accommodate users who wish to use `prefer-const` in some way but also want to consistently use `let` for runes.
ota-meshi: >  I want to accommodate users who wish to use prefer-const in some way but also want to consistently use let for runes.

If there are users requesting it, I think it makes sense to add the option.

Patch:
diff --git a/.changeset/blue-panthers-run.md b/.changeset/blue-panthers-run.md
deleted file mode 100644
index afb628d..0000000
--- a/.changeset/blue-panthers-run.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': patch
----
-
-fix: support each blocks without an item
diff --git a/.changeset/blue-swans-give.md b/.changeset/blue-swans-give.md
deleted file mode 100644
index 2d84a8c..0000000
--- a/.changeset/blue-swans-give.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': minor
----
-
-feat: Implement util to conditionally run lint based on Svelte version and SvelteKit routes etc
diff --git a/.changeset/brown-dots-change.md b/.changeset/brown-dots-change.md
deleted file mode 100644
index dfa797d..0000000
--- a/.changeset/brown-dots-change.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': minor
----
-
-feat: add Svelte 5 support to `no-not-function-handler`
diff --git a/.changeset/cold-starfishes-doubt.md b/.changeset/cold-starfishes-doubt.md
deleted file mode 100644
index f85c6b3..0000000
--- a/.changeset/cold-starfishes-doubt.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': minor
----
-
-feat: added the no-navigation-without-base rule
diff --git a/.changeset/cool-rockets-allow.md b/.changeset/cool-rockets-allow.md
deleted file mode 100644
index 338906c..0000000
--- a/.changeset/cool-rockets-allow.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': major
----
-
-feat!: drop support for old eslint
diff --git a/.changeset/cool-steaks-happen.md b/.changeset/cool-steaks-happen.md
deleted file mode 100644
index 8f6fc6f..0000000
--- a/.changeset/cool-steaks-happen.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': patch
----
-
-chore: upgrade `svelte-eslint-parser` to `1.0.0-next.8`
diff --git a/.changeset/cool-tomatoes-fry.md b/.changeset/cool-tomatoes-fry.md
deleted file mode 100644
index f61cd8f..0000000
--- a/.changeset/cool-tomatoes-fry.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': patch
----
-
-chore: change the rule category of `valid-prop-names-in-kit-pages` to `SvelteKit`
diff --git a/.changeset/early-trainers-know.md b/.changeset/early-trainers-know.md
deleted file mode 100644
index c379b37..0000000
--- a/.changeset/early-trainers-know.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': minor
----
-
-feat: added the `consistent-selector-style` rule
diff --git a/.changeset/eighty-trainers-push.md b/.changeset/eighty-trainers-push.md
deleted file mode 100644
index 8e8690a..0000000
--- a/.changeset/eighty-trainers-push.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': patch
----
-
-chore: add `:exit` for each node listener
diff --git a/.changeset/fast-coins-fly.md b/.changeset/fast-coins-fly.md
deleted file mode 100644
index 3169b1e..0000000
--- a/.changeset/fast-coins-fly.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': minor
----
-
-feat: Support `<svelte:boundary>`
diff --git a/.changeset/fifty-parents-itch.md b/.changeset/fifty-parents-itch.md
deleted file mode 100644
index c5f1b36..0000000
--- a/.changeset/fifty-parents-itch.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': minor
----
-
-feat: Added suggestion to the `block-lang` rule.
diff --git a/.changeset/gold-bottles-learn.md b/.changeset/gold-bottles-learn.md
deleted file mode 100644
index 2eb49d5..0000000
--- a/.changeset/gold-bottles-learn.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': patch
----
-
-fix: allow `children` in `valid-prop-names-in-kit-pages` rule
diff --git a/.changeset/gorgeous-cats-exercise.md b/.changeset/gorgeous-cats-exercise.md
deleted file mode 100644
index 2db770b..0000000
--- a/.changeset/gorgeous-cats-exercise.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-'eslint-plugin-svelte': major
----
-
-**Enabled in recommended config**:
-- `svelte/infinite-reactive-loop`
-- `svelte/no-dom-manipulating`
-- `svelte/no-dupe-on-directives`
-- `svelte/no-dupe-use-directives`
-- `svelte/no-export-load-in-svelte-module-in-kit-pages`
-- `svelte/no-immutable-reactive-statements`
-- `svelte/no-inspect`
-- `svelte/no-raw-special-elements`
-- `svelte/no-reactive-functions`
-- `svelte/no-reactive-literals`
-- `svelte/no-reactive-reassign`
-- `svelte/no-store-async`
-- `svelte/no-svelte-internal`
-- `svelte/no-useless-children-snippet`
-- `svelte/no-useless-mustaches`
-- `svelte/require-each-key`
-- `svelte/require-event-dispatcher-types`
-- `svelte/require-store-reactive-access`
-- `svelte/require-stores-init`
-- `svelte/valid-each-key`
-- `svelte/valid-prop-names-in-kit-pages`
-
-**Removed from recommended config**:
-- `svelte/valid-compile`
-
-This update introduces breaking changes due to newly enabled rules.
diff --git a/.changeset/great-turkeys-hang.md b/.changeset/great-turkeys-hang.md
deleted file mode 100644
index 992e3e8..0000000
--- a/.changeset/great-turkeys-hang.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': minor
----
-
-feat: support `warningFilter` in `valid-compile` rule
diff --git a/.changeset/green-squids-compete.md b/.changeset/green-squids-compete.md
deleted file mode 100644
index 7666a2a..0000000
--- a/.changeset/green-squids-compete.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': minor
----
-
-Add `prefer-const` rule
diff --git a/.changeset/grumpy-deers-film.md b/.changeset/grumpy-deers-film.md
deleted file mode 100644
index 7ac8178..0000000
--- a/.changeset/grumpy-deers-film.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': patch
----
-
-chore: change the rule category of `no-export-load-in-svelte-module-in-kit-pages` to `SvelteKit`
diff --git a/.changeset/hip-avocados-call.md b/.changeset/hip-avocados-call.md
deleted file mode 100644
index 850593e..0000000
--- a/.changeset/hip-avocados-call.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': patch
----
-
-chore: update `svelte-eslint-parser` to `1.0.0-next.10`
diff --git a/.changeset/hot-oranges-own.md b/.changeset/hot-oranges-own.md
deleted file mode 100644
index 49a4000..0000000
--- a/.changeset/hot-oranges-own.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"eslint-plugin-svelte": major
----
-
-feat: add `*.svelte.{js,ts}` config to base config
diff --git a/.changeset/hungry-grapes-shave.md b/.changeset/hungry-grapes-shave.md
deleted file mode 100644
index 67d3457..0000000
--- a/.changeset/hungry-grapes-shave.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': patch
----
-
-chore: update `svelte-eslint-parser` to v1.0.0-next.4
diff --git a/.changeset/itchy-dragons-boil.md b/.changeset/itchy-dragons-boil.md
deleted file mode 100644
index b87445b..0000000
--- a/.changeset/itchy-dragons-boil.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': patch
----
-
-chore: using svelte-eslint-parser for style selector parsing
diff --git a/.changeset/lazy-eyes-wait.md b/.changeset/lazy-eyes-wait.md
deleted file mode 100644
index 74f2c86..0000000
--- a/.changeset/lazy-eyes-wait.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': minor
----
-
-Added new `no-deprecated-raw-special-elements` rule
diff --git a/.changeset/loud-zoos-kiss.md b/.changeset/loud-zoos-kiss.md
deleted file mode 100644
index 74689a9..0000000
--- a/.changeset/loud-zoos-kiss.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': minor
----
-
-feat: added the no-useless-children-snippet rule
diff --git a/.changeset/nice-clocks-buy.md b/.changeset/nice-clocks-buy.md
deleted file mode 100644
index e7def69..0000000
--- a/.changeset/nice-clocks-buy.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': patch
----
-
-fix: ignore `css_unused_selector` compile error if `<style>` tag has `global` attribute
diff --git a/.changeset/nine-walls-hammer.md b/.changeset/nine-walls-hammer.md
deleted file mode 100644
index 9f45727..0000000
--- a/.changeset/nine-walls-hammer.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': patch
----
-
-chore: run `require-event-dispatcher-types` rule on Svelte 3/4 only
diff --git a/.changeset/old-numbers-pull.md b/.changeset/old-numbers-pull.md
deleted file mode 100644
index 9bcf48b..0000000
--- a/.changeset/old-numbers-pull.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': patch
----
-
-fix: account for \n and \r in `TemplateLiteral` handling for the `no-useless-mustaches` rule
diff --git a/.changeset/olive-melons-explain.md b/.changeset/olive-melons-explain.md
deleted file mode 100644
index 2b8259c..0000000
--- a/.changeset/olive-melons-explain.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': major
----
-
-breaking: deprecated the no-goto-without-base rule
diff --git a/.changeset/olive-spiders-type.md b/.changeset/olive-spiders-type.md
deleted file mode 100644
index 6365268..0000000
--- a/.changeset/olive-spiders-type.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': patch
----
-
-chore: update `svelte-eslint-parser` to `1.0.0-next.9`
diff --git a/.changeset/olive-squids-design.md b/.changeset/olive-squids-design.md
deleted file mode 100644
index 0b31d53..0000000
--- a/.changeset/olive-squids-design.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': patch
----
-
-chore: do not run `no-reactive-functions` rule on Svelte 5 with runes
diff --git a/.changeset/olive-wolves-travel.md b/.changeset/olive-wolves-travel.md
deleted file mode 100644
index 88f7871..0000000
--- a/.changeset/olive-wolves-travel.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"eslint-plugin-svelte": major
----
-
-feat!: drop support for old node versions (<18, 19, 21)
diff --git a/.changeset/perfect-mirrors-doubt.md b/.changeset/perfect-mirrors-doubt.md
deleted file mode 100644
index 413a80f..0000000
--- a/.changeset/perfect-mirrors-doubt.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': patch
----
-
-chore: do not run `no-reactive-reassign` rule on Svelte 5 with runes
diff --git a/.changeset/pre.json b/.changeset/pre.json
deleted file mode 100644
index 54865cc..0000000
--- a/.changeset/pre.json
+++ /dev/null
@@ -1,55 +0,0 @@
-{
-  "mode": "pre",
-  "tag": "next",
-  "initialVersions": {
-    "eslint-plugin-svelte": "2.46.0",
-    "docs": "0.0.0"
-  },
-  "changesets": [
-    "blue-panthers-run",
-    "blue-swans-give",
-    "brown-dots-change",
-    "cold-starfishes-doubt",
-    "cool-rockets-allow",
-    "cool-steaks-happen",
-    "cool-tomatoes-fry",
-    "early-trainers-know",
-    "eighty-trainers-push",
-    "fast-coins-fly",
-    "fifty-parents-itch",
-    "gold-bottles-learn",
-    "gorgeous-cats-exercise",
-    "great-turkeys-hang",
-    "green-squids-compete",
-    "grumpy-deers-film",
-    "hip-avocados-call",
-    "hot-oranges-own",
-    "hungry-grapes-shave",
-    "itchy-dragons-boil",
-    "lazy-eyes-wait",
-    "loud-zoos-kiss",
-    "nice-clocks-buy",
-    "nine-walls-hammer",
-    "old-numbers-pull",
-    "olive-melons-explain",
-    "olive-spiders-type",
-    "olive-squids-design",
-    "olive-wolves-travel",
-    "perfect-mirrors-doubt",
-    "quiet-toys-burn",
-    "real-birds-move",
-    "red-jokes-tickle",
-    "sixty-news-look",
-    "small-days-agree",
-    "small-donuts-end",
-    "smart-apes-confess",
-    "smart-brooms-relax",
-    "soft-bears-hear",
-    "stale-bobcats-laugh",
-    "swift-clocks-turn",
-    "thick-items-retire",
-    "thin-dryers-know",
-    "twenty-nails-end",
-    "two-students-pump"
-  ]
-}
diff --git a/.changeset/quiet-toys-burn.md b/.changeset/quiet-toys-burn.md
deleted file mode 100644
index 6c7c311..0000000
--- a/.changeset/quiet-toys-burn.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': minor
----
-
-feat: support for typescript-eslint v8 to `svelte/indent` rule
diff --git a/.changeset/real-birds-move.md b/.changeset/real-birds-move.md
deleted file mode 100644
index 82f0200..0000000
--- a/.changeset/real-birds-move.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': major
----
-
-breaking: deprecate the `svelte/no-dynamic-slot-name` rule
diff --git a/.changeset/red-jokes-tickle.md b/.changeset/red-jokes-tickle.md
deleted file mode 100644
index ab06d7f..0000000
--- a/.changeset/red-jokes-tickle.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': patch
----
-
-chore: update `svelte-eslint-parser` to `v1.0.0-next.12`
diff --git a/.changeset/sixty-cars-fail.md b/.changeset/sixty-cars-fail.md
new file mode 100644
index 0000000..b98c40f
--- /dev/null
+++ b/.changeset/sixty-cars-fail.md
@@ -0,0 +1,5 @@
+---
+'eslint-plugin-svelte': minor
+---
+
+feat: add `excludedRunes` option to the `prefer-const` rule
diff --git a/.changeset/sixty-news-look.md b/.changeset/sixty-news-look.md
deleted file mode 100644
index e70b9cd..0000000
--- a/.changeset/sixty-news-look.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': minor
----
-
-feat: support Svelte5 of `valid-prop-names-in-kit-pages` rule
diff --git a/.changeset/small-days-agree.md b/.changeset/small-days-agree.md
deleted file mode 100644
index febff4e..0000000
--- a/.changeset/small-days-agree.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"eslint-plugin-svelte": major
----
-
-feat!: upgrade svelte-eslint-parser to v1
diff --git a/.changeset/small-donuts-end.md b/.changeset/small-donuts-end.md
deleted file mode 100644
index ec0f648..0000000
--- a/.changeset/small-donuts-end.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': patch
----
-
-fix: crash with eslint v9.16.0 in `svelte/no-inner-declarations`
diff --git a/.changeset/smart-apes-confess.md b/.changeset/smart-apes-confess.md
deleted file mode 100644
index 922c2c9..0000000
--- a/.changeset/smart-apes-confess.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': patch
----
-
-chore: run the `no-inspect` rule only in Svelte 5’s runes mode
diff --git a/.changeset/smart-brooms-relax.md b/.changeset/smart-brooms-relax.md
deleted file mode 100644
index ee9ebe8..0000000
--- a/.changeset/smart-brooms-relax.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': patch
----
-
-chore: do not run `infinite-reactive-loop` rule on Svelte 5 with runes
diff --git a/.changeset/soft-bears-hear.md b/.changeset/soft-bears-hear.md
deleted file mode 100644
index d54cb5b..0000000
--- a/.changeset/soft-bears-hear.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': major
----
-
-feat!: Updated the `html-self-closing` rule to follow Svelte5
diff --git a/.changeset/stale-bobcats-laugh.md b/.changeset/stale-bobcats-laugh.md
deleted file mode 100644
index 8f6b5f0..0000000
--- a/.changeset/stale-bobcats-laugh.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': patch
----
-
-chore: do not run `no-reactive-literals` rule on Svelte 5 with runes
diff --git a/.changeset/swift-clocks-turn.md b/.changeset/swift-clocks-turn.md
deleted file mode 100644
index f91bc65..0000000
--- a/.changeset/swift-clocks-turn.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': patch
----
-
-chore: run `no-useless-children-snippet` rule on Svelte 5 only
diff --git a/.changeset/thick-items-retire.md b/.changeset/thick-items-retire.md
deleted file mode 100644
index 534550c..0000000
--- a/.changeset/thick-items-retire.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"eslint-plugin-svelte": major
----
-
-feat!: change the plugin to an ESM-only package
diff --git a/.changeset/thin-dryers-know.md b/.changeset/thin-dryers-know.md
deleted file mode 100644
index b98f20f..0000000
--- a/.changeset/thin-dryers-know.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': minor
----
-
-fix!: rename `no-deprecated-raw-special-elements` to `no-raw-special-elements`
diff --git a/.changeset/twenty-nails-end.md b/.changeset/twenty-nails-end.md
deleted file mode 100644
index 9efebd7..0000000
--- a/.changeset/twenty-nails-end.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': minor
----
-
-feat(no-inline-styles): allowing transitions by default
diff --git a/.changeset/two-students-pump.md b/.changeset/two-students-pump.md
deleted file mode 100644
index c0e36c9..0000000
--- a/.changeset/two-students-pump.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'eslint-plugin-svelte': patch
----
-
-fix: update method for extracting major version
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 4c273be..1f1d954 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,6 +1,6 @@
 # Contributing
 
-Thanks for contributing!
+Thank you for contributing!
 
 ## Installation
 
@@ -10,62 +10,60 @@ cd eslint-plugin-svelte
 pnpm install
 ```
 
-## Running the tests
+## Running Tests
 
 ```sh
+cd packages/eslint-plugin-svelte
 pnpm run test
 ```
 
-To run the tests with debugging log, you can use `pnpm run test:debug`.
+This is an [ESLint](http://eslint.org) plugin. See ESLint's [Working with Plugins](http://eslint.org/docs/developer-guide/working-with-plugins) for API details.
 
-This is an [ESLint](http://eslint.org) plugin. Documentation for the APIs that it uses can be found on ESLint's [Working with Plugins](http://eslint.org/docs/developer-guide/working-with-plugins) page.
-
-This plugin is used to lint itself. The style is checked when `pnpm run lint` is run, and the build will fail if there are any linting errors. You can use `pnpm run lint-fix` to fix some linting errors.
+The plugin lints itself. Running `pnpm run lint` checks the style and will fail the build if there are lint errors. Use `pnpm run lint-fix` to automatically fix some issues.
 
 ## Other Development Tools
 
-- `pnpm run test` runs tests.
-- `pnpm run cover` runs tests and measures coverage.
-- `pnpm run new -- [new-rule-name]` generate the files needed to implement the new rule.
-- `pnpm run update` runs in order to update readme and recommended configuration.
-- `pnpm run docs:watch` launch the document site in development mode.
+- `pnpm run test` – runs tests.
+- `pnpm run new -- [new-rule-name]` – generates files for a new rule.
+- `pnpm run update` – updates the README and recommended configuration.
 
-## Test the Rule
+## Rule Testing
 
-Rule testing almost always uses fixtures.  
-For example, for an `indent` rule, the `.ts` file that runs the test is `tests/src/rules/indent.ts` and the fixture is in `tests/fixtures/rules/indent`.  
-The fixture directory has an `invalid` directory and a `valid` directory.
+Rule tests typically use fixtures. For example, for the `indent` rule, the test file is `tests/src/rules/indent.ts` and the fixtures are in `tests/fixtures/rules/indent`, which contains `invalid` and `valid` directories.
 
-- The `invalid` directory contains test cases where the rule reports problems.
-- The `valid` directory contains test cases where the rule does not report a problem.
+- The `invalid` directory contains test cases where the rule should report errors.
+- The `valid` directory contains test cases where no errors are reported.
 
-The fixture input file should be named `*-input.svelte`. It is automatically collected and tested.  
-If your test requires configuration, you need to add a json file with the configuration.
+Fixture input files should be named `*-input.svelte` and are automatically collected.  
+If configuration is needed, include a JSON file:
 
-- If you want to apply a configuration to `my-test-input.svelte`, add `my-test-config.json`.
-- If you want to apply the same configuration to all the fixtures in that directory, add `_config.json`.
+- For a specific test file (e.g., `my-test-input.svelte`), add `my-test-config.json`.
+- For all fixtures in a directory, add `_config.json`.
 
-To verify the output of invalid test cases requires `*-errors.json`, and `*-output.svelte` (for auto-fix). However, you don't have to add them yourself. If they do not exist, they will be automatically generated when you run the test. In other words, delete them manually when you want to recreate them.
+Verifying output for invalid tests requires `*-errors.json` and `*-output.svelte` (for auto-fix). These files are auto-generated if missing—delete them to recreate.
 
 **Tips**:
 
-If you want to test only one rule, run the following command (for `indent` rule):
+To test only one rule (e.g., `indent`), run:
 
 ```sh
 pnpm run test -- -g indent
 ```
 
-Take <https://stackoverflow.com/questions/10832031/how-to-run-a-single-test-with-mocha> as reference for details.
+Refer to [this Stack Overflow post](https://stackoverflow.com/questions/10832031/how-to-run-a-single-test-with-mocha) for details.
 
-If you want to test only `my-test-input.svelte`, add `my-test-config.json` and save `{"only": true}`.  
-(Note that `{"only": true}` must be removed before making a pull request.)
+To test a single file (e.g., `my-test-input.svelte`), add a `my-test-config.json` with `{"only": true}`.  
+(Remember to remove `{"only": true}` before submitting a pull request.)
 
-## Commit messages
+## Preview Docs
 
-Please view [commitlint](https://commitlint.js.org) and [@commitlint/config-conventional](https://github.com/conventional-changelog/commitlint/tree/master/%40commitlint/config-conventional) for more details.
+```sh
+cd docs-svelte-kit
+pnpm run build && pnpm run preview
+```
 
 ## Publishing
 
-We're using [changesets](https://github.com/changesets/changesets) for version management, CHANGELOG and releasing automatically.
+We use [changesets](https://github.com/changesets/changesets) for version management, changelog generation, and automated releases.
 
-Please view [changesets-bot](https://github.com/apps/changeset-bot) and its [action](https://github.com/changesets/action) for more details.
+For more details, see [changesets-bot](https://github.com/apps/changeset-bot) and its [action](https://github.com/changesets/action).
diff --git a/README.md b/README.md
index 01eb6bd..351738e 100644
--- a/README.md
+++ b/README.md
@@ -1,14 +1,4 @@
-# Introduction
-
-`eslint-plugin-svelte` is the official [ESLint] plugin for [Svelte].  
-It provides many unique check rules by using the template AST.  
-You can check on the [Online DEMO](https://eslint-online-playground.netlify.app/#eslint-plugin-svelte%20with%20typescript).
-
-> [!NOTE]
-> This document is in development.\
-> Please refer to the document for the version you are using.\
-> For example, <https://github.com/sveltejs/eslint-plugin-svelte/blob/eslint-plugin-svelte%402.46.0/README.md>
-> and <https://github.com/sveltejs/eslint-plugin-svelte/blob/eslint-plugin-svelte%402.46.0/docs>
+<!--DOCS_IGNORE_START-->
 
 [![NPM license](https://img.shields.io/npm/l/eslint-plugin-svelte.svg)](https://www.npmjs.com/package/eslint-plugin-svelte)
 [![NPM version](https://img.shields.io/npm/v/eslint-plugin-svelte.svg)](https://www.npmjs.com/package/eslint-plugin-svelte)
@@ -24,209 +14,197 @@ You can check on the [Online DEMO](https://eslint-online-playground.netlify.app/
 [![Code Style: Prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier)
 [![changesets](https://img.shields.io/badge/maintained%20with-changesets-176de3.svg)](https://github.com/atlassian/changesets)
 
-## :name_badge: What is this plugin?
+<div align="center">
 
-[ESLint] plugin for [Svelte].  
-It provides many unique check rules using the AST generated by [svelte-eslint-parser].
+# eslint-plugin-svelte
 
-### ❗ Attention
+## ESLint plugin for Svelte using AST
 
-#### Cannot be used with eslint-plugin-svelte3
+[Live Demo](https://eslint-online-playground.netlify.app/#eslint-plugin-svelte%20with%20typescript) •
+[Documentation](https://sveltejs.github.io/eslint-plugin-svelte/) •
+[Discord](https://svelte.dev/chat)
 
-The [svelte-eslint-parser] and the `eslint-plugin-svelte` can not be used with the [eslint-plugin-svelte3].
+</div>
 
-[svelte-eslint-parser]: https://github.com/sveltejs/svelte-eslint-parser
-[eslint-plugin-svelte3]: https://github.com/sveltejs/eslint-plugin-svelte3
-
-#### Experimental support for Svelte v5
-
-We are working on support for Svelte v5, but it is still an experimental feature. Please note that rules and features related to Svelte v5 may be changed or removed in minor versions without notice.
-
-<!--DOCS_IGNORE_START-->
-
-## Versioning policy
-
-This plugin follows [Semantic Versioning](https://semver.org/).  
-However, unlike [ESLint’s Semantic Versioning Policy](https://github.com/eslint/eslint#semantic-versioning-policy), this plugin adds new rules to its configs even in minor releases. For example, if you are using the recommended config, a minor update may add new rules, which could cause new lint errors in your project.  
-While [ESLint’s Semantic Versioning Policy](https://github.com/eslint/eslint#semantic-versioning-policy) only adds new rules to configs in major releases, most users (myself included) don’t regularly monitor new rules. This makes it challenging to manually add them to projects whenever they are introduced.  
-By adding new rules to configs in minor releases, this plugin ensures users can adopt them more easily. If any new rules cause issues, you can simply disable them. I believe this approach helps maintain and improve code quality with minimal effort.
-
-## Migration Guide
+<!--DOCS_IGNORE_END-->
 
-To migrate from `eslint-plugin-svelte` v1, or [`@ota-meshi/eslint-plugin-svelte`](https://www.npmjs.com/package/@ota-meshi/eslint-plugin-svelte), please refer to the [migration guide](https://sveltejs.github.io/eslint-plugin-svelte/migration/).
+## Introduction
 
-## :book: Documentation
+`eslint-plugin-svelte` is the official [ESLint](https://eslint.org/) plugin for [Svelte](https://svelte.dev/).  
+It leverages the AST generated by [svelte-eslint-parser](https://github.com/sveltejs/svelte-eslint-parser) to provide custom linting for Svelte.  
+Note that `eslint-plugin-svelte` and `svelte-eslint-parser` cannot be used alongside [eslint-plugin-svelte3](https://github.com/sveltejs/eslint-plugin-svelte3).
 
-See [documents](https://sveltejs.github.io/eslint-plugin-svelte/).
+<!--USAGE_SECTION_START-->
+<!--USAGE_GUIDE_START-->
 
-## :cd: Installation
+## Installation
 
 ```bash
-npm install --save-dev eslint eslint-plugin-svelte svelte
+npm install --save-dev svelte eslint eslint-plugin-svelte globals
 ```
 
-> **Requirements**
+> [!NOTE]
 >
-> - ESLint v8.57.1, v9.0.0 and above
-> - Node.js v18.20.4, v20.18.0, v22.10.0 and above
-
-<!--DOCS_IGNORE_END-->
+> **Requirements:**
+>
+> - ESLint v8.57.1, v9.0.0, and above
+> - Node.js v18.20.4, v20.18.0, v22.10.0, and above
 
-## :book: Usage
+## Usage
 
-<!--USAGE_SECTION_START-->
-<!--USAGE_GUIDE_START-->
+Use the `eslint.config.js` file to configure rules. For more details, see the [ESLint documentation](https://eslint.org/docs/latest/use/configure/configuration-files-new).
 
 ### Configuration
 
-Use `eslint.config.js` file to configure rules. See also: <https://eslint.org/docs/latest/use/configure/configuration-files-new>.
-
-Example **eslint.config.js**:
+#### JavaScript project
 
 ```js
-import eslintPluginSvelte from 'eslint-plugin-svelte';
-export default [
-  // add more generic rule sets here, such as:
-  // js.configs.recommended,
-  ...eslintPluginSvelte.configs.recommended,
-  {
-    rules: {
-      // override/add rules settings here, such as:
-      // 'svelte/rule-name': 'error'
-    }
-  }
-];
-```
-
-This plugin provides configs:
-
-- `eslintPluginSvelte.configs.base` ... Configuration to enable correct Svelte parsing.
-- `eslintPluginSvelte.configs.recommended` ... Above, plus rules to prevent errors or unintended behavior.
-- `eslintPluginSvelte.configs.prettier` ... Turns off rules that may conflict with [Prettier](https://prettier.io/) (You still need to configure prettier to work with svelte yourself, for example by using [prettier-plugin-svelte](https://github.com/sveltejs/prettier-plugin-svelte).).
-- `eslintPluginSvelte.configs.all` ... All rules. This configuration is not recommended for production use because it changes with every minor and major version of `eslint-plugin-svelte`. Use it at your own risk.
-
-See [the rule list](https://sveltejs.github.io/eslint-plugin-svelte/rules/) to get the `rules` that this plugin provides.
-
-#### Parser Configuration
-
-If you have specified a parser, you need to configure a parser for `.svelte`.
-
-For example, if you are using the `"@typescript-eslint/parser"`, and if you want to use TypeScript in `<script>` of `.svelte`, you need to add more `parserOptions` configuration.
+// eslint.config.js
+import js from '@eslint/js';
+import svelte from 'eslint-plugin-svelte';
+import globals from 'globals';
+import svelteConfig from './svelte.config.js';
 
-```js
-import eslintPluginSvelte from 'eslint-plugin-svelte';
-import * as svelteParser from 'svelte-eslint-parser';
-import * as typescriptParser from '@typescript-eslint/parser';
+/** @type {import('eslint').Linter.Config[]} */
 export default [
-  ...js.configs.recommended,
-  ...eslintPluginSvelte.configs.recommended,
+  js.configs.recommended,
+  ...svelte.configs.recommended,
   {
-    files: ['**/*.svelte'],
     languageOptions: {
-      parser: svelteParser,
-      parserOptions: {
-        parser: typescriptParser,
-        project: './path/to/your/tsconfig.json',
-        extraFileExtensions: ['.svelte']
+      globals: {
+        ...globals.browser,
+        ...globals.node // Add this if you are using SvelteKit in non-SPA mode
       }
     }
-  }
-];
-```
-
-If you have a mix of TypeScript and JavaScript in your project, use a multiple parser configuration.
-
-```js
-import eslintPluginSvelte from 'eslint-plugin-svelte';
-import * as svelteParser from 'svelte-eslint-parser';
-import * as typescriptParser from '@typescript-eslint/parser';
-import espree from 'espree';
-export default [
-  ...js.configs.recommended,
-  ...eslintPluginSvelte.configs.recommended,
+  },
   {
-    files: ['**/*.svelte'],
+    files: ['**/*.svelte', '**/*.svelte.js'],
     languageOptions: {
-      parser: svelteParser,
       parserOptions: {
-        parser: {
-          // Specify a parser for each lang.
-          ts: typescriptParser,
-          js: espree,
-          typescript: typescriptParser
-        },
-        project: './path/to/your/tsconfig.json',
-        extraFileExtensions: ['.svelte']
+        // We recommend importing and specifying svelte.config.js.
+        // By doing so, some rules in eslint-plugin-svelte will automatically read the configuration and adjust their behavior accordingly.
+        // While certain Svelte settings may be statically loaded from svelte.config.js even if you don’t specify it,
+        // explicitly specifying it ensures better compatibility and functionality.
+        svelteConfig
       }
     }
+  },
+  {
+    rules: {
+      // Override or add rule settings here, such as:
+      // 'svelte/rule-name': 'error'
+    }
   }
 ];
 ```
 
-See also <https://github.com/sveltejs/svelte-eslint-parser#readme>.
+#### TypeScript project
 
-::: warning ❗ Attention
-
-The TypeScript parser uses a singleton internally and it will only use the
-options given to it when it was first initialized. If trying to change the
-options for a different file or override, the parser will simply ignore the new
-options (which may result in an error). See
-[typescript-eslint/typescript-eslint#6778](https://github.com/typescript-eslint/typescript-eslint/issues/6778)
-for some context.
-
-:::
-
-#### Specify `svelte.config.js`
-
-If you are using `eslint.config.js`, we recommend that you import and specify `svelte.config.js`.
-By specifying it, some rules of `eslint-plugin-svelte` will read it and try to behave well for you by default.
-Some Svelte configurations will be statically loaded from `svelte.config.js` even if you don't specify it, but you need to specify it to make it work better.
-
-Example **eslint.config.js**:
+```shell
+npm install --save-dev typescript-eslint
+```
 
 ```js
-import eslintPluginSvelte from 'eslint-plugin-svelte';
+// eslint.config.js
+import js from '@eslint/js';
+import svelte from 'eslint-plugin-svelte';
+import globals from 'globals';
+import ts from 'typescript-eslint';
 import svelteConfig from './svelte.config.js';
-export default [
-  ...eslintPluginSvelte.configs.recommended,
+
+export default ts.config(
+  js.configs.recommended,
+  ...ts.configs.recommended,
+  ...svelte.configs.recommended,
+  {
+    languageOptions: {
+      globals: {
+        ...globals.browser,
+        ...globals.node
+      }
+    }
+  },
   {
-    files: [
-      '**/*.svelte',
-      '*.svelte'
-      // Add more files if you need.
-      // '**/*.svelte.ts', '*.svelte.ts', '**/*.svelte.js', '*.svelte.js',
-    ],
+    files: ['**/*.svelte', '**/*.svelte.ts', '**/*.svelte.js'],
+    // See more details at: https://typescript-eslint.io/packages/parser/
     languageOptions: {
       parserOptions: {
-        // Specify the `svelte.config.js`.
+        projectService: true,
+        extraFileExtensions: ['.svelte'], // Add support for additional file extensions, such as .svelte
+        parser: ts.parser,
+        // Specify a parser for each language, if needed:
+        // parser: {
+        //   ts: ts.parser,
+        //   js: espree,    // Use espree for .js files (add: import espree from 'espree')
+        //   typescript: ts.parser
+        // },
+
+        // We recommend importing and specifying svelte.config.js.
+        // By doing so, some rules in eslint-plugin-svelte will automatically read the configuration and adjust their behavior accordingly.
+        // While certain Svelte settings may be statically loaded from svelte.config.js even if you don’t specify it,
+        // explicitly specifying it ensures better compatibility and functionality.
         svelteConfig
       }
     }
+  },
+  {
+    rules: {
+      // Override or add rule settings here, such as:
+      // 'svelte/rule-name': 'error'
+    }
   }
-];
+);
 ```
 
-#### settings.svelte
+> [!WARNING]
+> The TypeScript parser uses a singleton internally, meaning it only respects the options provided during its initial initialization.
+> If you try to change the options for a different file or override them later, the parser will ignore the new options, which may lead to errors.
+> For more context, see [typescript-eslint/typescript-eslint#6778](https://github.com/typescript-eslint/typescript-eslint/issues/6778).
+
+### Available Configurations
+
+This plugin provides the following configurations:
 
-You can change the behavior of this plugin with some settings.
+- **`eslintPluginSvelte.configs.base`** ... Enables correct Svelte parsing.
+- **`eslintPluginSvelte.configs.recommended`** ... Includes `base` configuration, plus rules to prevent errors or unintended behavior.
+- **`eslintPluginSvelte.configs.prettier`** ... Disables rules that may conflict with [Prettier](https://prettier.io/). You still need to configure Prettier to work with Svelte manually, for example, by using [prettier-plugin-svelte](https://github.com/sveltejs/prettier-plugin-svelte).
+- **`eslintPluginSvelte.configs.all`** ... Includes all available rules. **Note:** This configuration is not recommended for production use, as it changes with every minor and major version of `eslint-plugin-svelte`. Use at your own risk.
 
-e.g.
+For more details, see [the rule list](https://sveltejs.github.io/eslint-plugin-svelte/rules/) to explore the rules provided by this plugin.
+
+### settings.svelte
+
+You can customize the behavior of this plugin using specific settings.
 
 ```js
+// eslint.config.js
 export default [
   // ...
   {
     settings: {
       svelte: {
+        // Specifies an array of rules to ignore reports within the template.
+        // For example, use this to disable rules in the template that may produce unavoidable false positives.
         ignoreWarnings: [
           '@typescript-eslint/no-unsafe-assignment',
           '@typescript-eslint/no-unsafe-member-access'
         ],
+        // Specifies options for Svelte compilation.
+        // This affects rules that rely on Svelte compilation,
+        // such as svelte/valid-compile and svelte/no-unused-svelte-ignore.
+        // Note that this setting does not impact ESLint’s custom parser.
         compileOptions: {
+          // Specifies options related to PostCSS. You can disable the PostCSS processing by setting it to false.
           postcss: {
+            // Specifies the path to the directory that contains the PostCSS configuration.
             configFilePath: './path/to/my/postcss.config.js'
           }
         },
+        // Even if settings.svelte.kit is not specified, the rules will attempt to load information from svelte.config.js.
+        // However, if the default behavior does not work as expected, you should specify settings.svelte.kit explicitly.
+        // If you are using SvelteKit with a non-default configuration, you need to set the following options.
+        // The schema is a subset of SvelteKit’s configuration, so refer to the SvelteKit documentation for more details.
+        // https://svelte.dev/docs/kit/configuration
         kit: {
           files: {
             routes: 'src/routes'
@@ -239,59 +217,11 @@ export default [
 ];
 ```
 
-#### settings.svelte.ignoreWarnings
-
-Specifies an array of rules that ignore reports in the template.  
-For example, set rules on the template that cannot avoid false positives.
-
-#### settings.svelte.compileOptions
-
-Specifies options for Svelte compile. Effects rules that use Svelte compile. The target rules are [svelte/valid-compile](https://sveltejs.github.io/eslint-plugin-svelte/rules/valid-compile/) and [svelte/no-unused-svelte-ignore](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-unused-svelte-ignore/). **Note that it has no effect on ESLint's custom parser**.
-
-- `postcss` ... Specifies options related to PostCSS. You can disable the PostCSS process by specifying `false`.
-  - `configFilePath` ... Specifies the path of the directory containing the PostCSS configuration.
-
-#### settings.svelte.kit
-
-::: warning
-
-Even if you don't specify `settings.svelte.kit`, the rules will try to load information from `svelte.config.js`, so specify `settings.svelte.kit` if the default doesn't work.
-
-:::
-
-If you use SvelteKit with not default configuration, you need to set below configurations.
-The schema is subset of SvelteKit's configuration.
-Therefore please check [SvelteKit docs](https://kit.svelte.dev/docs/configuration) for more details.
-
-e.g.
-
-```js
-export default [
-  // ...
-  {
-    settings: {
-      svelte: {
-        kit: {
-          files: {
-            routes: 'src/routes'
-          }
-        }
-      }
-    }
-  }
-  // ...
-];
-```
-
-## :computer: Editor Integrations
-
-### Visual Studio Code
+## Editor Integrations
 
-Use the [dbaeumer.vscode-eslint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) extension that Microsoft provides officially.
-
-You have to configure the `eslint.validate` option of the extension to check `.svelte` files, because the extension targets only `*.js` or `*.jsx` files by default.
-
-Example **.vscode/settings.json**:
+**Visual Studio Code**  
+Install [dbaeumer.vscode-eslint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint).  
+Configure `.svelte` files in `.vscode/settings.json`:
 
 ```json
 {
@@ -302,7 +232,17 @@ Example **.vscode/settings.json**:
 <!--USAGE_GUIDE_END-->
 <!--USAGE_SECTION_END-->
 
-## :white_check_mark: Rules
+## Migration Guide
+
+If you’re migrating from `eslint-plugin-svelte` v1 or [`@ota-meshi/eslint-plugin-svelte`](https://www.npmjs.com/package/@ota-meshi/eslint-plugin-svelte), see the [migration guide](https://sveltejs.github.io/eslint-plugin-svelte/migration/).
+
+## Versioning Policy
+
+This project follows [Semantic Versioning](https://semver.org/). Unlike [ESLint’s versioning policy](https://github.com/eslint/eslint#semantic-versioning-policy), new rules may be added to the recommended config in minor releases. If these rules cause unwanted warnings, you can disable them.
+
+<!--DOCS_IGNORE_END-->
+
+## Rules
 
 <!-- prettier-ignore-start -->
 <!--RULES_SECTION_START-->
@@ -335,6 +275,7 @@ These rules relate to possible syntax or logic errors in Svelte code:
 | [svelte/require-store-callbacks-use-set-param](https://sveltejs.github.io/eslint-plugin-svelte/rules/require-store-callbacks-use-set-param/) | store callbacks must use `set` param |  |
 | [svelte/require-store-reactive-access](https://sveltejs.github.io/eslint-plugin-svelte/rules/require-store-reactive-access/) | disallow to use of the store itself as an operand. Need to use $ prefix or get function. | :star::wrench: |
 | [svelte/valid-compile](https://sveltejs.github.io/eslint-plugin-svelte/rules/valid-compile/) | disallow warnings when compiling. |  |
+| [svelte/valid-style-parse](https://sveltejs.github.io/eslint-plugin-svelte/rules/valid-style-parse/) | require valid style element parsing |  |
 
 ## Security Vulnerability
 
@@ -370,7 +311,7 @@ These rules relate to better ways of doing things to help you avoid problems:
 | [svelte/require-each-key](https://sveltejs.github.io/eslint-plugin-svelte/rules/require-each-key/) | require keyed `{#each}` block | :star: |
 | [svelte/require-event-dispatcher-types](https://sveltejs.github.io/eslint-plugin-svelte/rules/require-event-dispatcher-types/) | require type parameters for `createEventDispatcher` | :star: |
 | [svelte/require-optimized-style-attribute](https://sveltejs.github.io/eslint-plugin-svelte/rules/require-optimized-style-attribute/) | require style attributes that can be optimized |  |
-| [svelte/require-stores-init](https://sveltejs.github.io/eslint-plugin-svelte/rules/require-stores-init/) | require initial value in store | :star: |
+| [svelte/require-stores-init](https://sveltejs.github.io/eslint-plugin-svelte/rules/require-stores-init/) | require initial value in store |  |
 | [svelte/valid-each-key](https://sveltejs.github.io/eslint-plugin-svelte/rules/valid-each-key/) | enforce keys to use variables defined in the `{#each}` block | :star: |
 
 ## Stylistic Issues
@@ -453,23 +394,13 @@ These rules relate to this plugin works:
 
 <!--DOCS_IGNORE_START-->
 
-## :beers: Contributing
-
-Welcome contributing!
-
-Please use GitHub's Issues/PRs.
+## Contributing
 
-See also [CONTRIBUTING.md](./CONTRIBUTING.md)
-
-### Working With Rules
-
-This plugin uses [svelte-eslint-parser](https://github.com/sveltejs/svelte-eslint-parser) for the parser. Check [here](https://sveltejs.github.io/svelte-eslint-parser/) to find out about AST.
+Contributions are welcome! Please open an issue or submit a PR. For more details, see [CONTRIBUTING.md](./CONTRIBUTING.md).  
+Refer to [svelte-eslint-parser](https://github.com/sveltejs/svelte-eslint-parser) for AST details.
 
 <!--DOCS_IGNORE_END-->
 
-## :lock: License
-
-See the [LICENSE](LICENSE) file for license rights and limitations (MIT).
+## License
 
-[svelte]: https://svelte.dev/
-[eslint]: https://eslint.org/
+See [LICENSE](LICENSE) (MIT).
diff --git a/docs-svelte-kit/package.json b/docs-svelte-kit/package.json
index e6fb687..6ea86fb 100644
--- a/docs-svelte-kit/package.json
+++ b/docs-svelte-kit/package.json
@@ -16,8 +16,8 @@
     "@babel/types": "^7.26.0",
     "@fontsource/fira-mono": "^5.1.0",
     "@ota-meshi/eslint-plugin": "^0.17.6",
-    "@shikijs/markdown-it": "^2.0.0",
-    "@shikijs/twoslash": "^2.0.0",
+    "@shikijs/markdown-it": "^3.0.0",
+    "@shikijs/twoslash": "^3.0.0",
     "@sindresorhus/slugify": "^2.2.1",
     "@sveltejs/adapter-static": "^3.0.6",
     "@sveltejs/kit": "^2.8.5",
@@ -45,7 +45,7 @@
     "eslint-scope": "^8.2.0",
     "eslint-visitor-keys": "^4.2.0",
     "espree": "^10.3.0",
-    "globals": "^15.12.0",
+    "globals": "^16.0.0",
     "markdown-it-anchor": "^9.2.0",
     "markdown-it-container": "^4.0.0",
     "markdown-it-emoji": "^3.0.0",
@@ -58,8 +58,8 @@
     "stylus": "^0.64.0",
     "svelte": "^5.2.10",
     "svelte-adapter-ghpages": "0.2.2",
-    "twoslash-eslint": "^0.2.12",
-    "twoslash-protocol": "^0.2.12",
+    "twoslash-eslint": "^0.3.0",
+    "twoslash-protocol": "^0.3.0",
     "util": "^0.12.5",
     "vite": "^6.0.1",
     "vite-plugin-svelte-md": "^0.1.7"
diff --git a/docs-svelte-kit/src/app.css b/docs-svelte-kit/src/app.css
index 7ab76d3..f8a94c4 100644
--- a/docs-svelte-kit/src/app.css
+++ b/docs-svelte-kit/src/app.css
@@ -1,105 +1,226 @@
-@import "@fontsource/fira-mono";
+@import '@fontsource/fira-mono';
+@import 'prismjs/themes/prism-tomorrow';
+@import '@shikijs/twoslash/style-rich.css';
 
 :root {
-  font-family: Arial, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
-    Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
-  --font-mono: "Fira Mono", monospace;
-  --pure-white: #ffffff;
-  --primary-color: #b9c6d2;
-  --secondary-color: #676778;
-  --tertiary-color: #edf0f8;
-  --accent-color: #ff3e00;
-  --heading-color: rgba(0, 0, 0, 0.7);
-  --text-color: #444444;
-  --background-without-opacity: rgba(255, 255, 255, 0.7);
-  --column-width: 42rem;
-  --column-margin-top: 4rem;
+	font-family: 'Inter', 'Helvetica Neue', 'Arial', sans-serif;
+	--font-mono: 'Fira Mono', monospace;
+	--pure-white: #ffffff;
+	--primary-color: #ffffff;
+	--secondary-color: #676778;
+	--tertiary-color: #edf0f8;
+	--accent-color: #ff3e00;
+	--heading-color: rgba(0, 0, 0, 0.7);
+	--text-color: #444444;
+	--background-without-opacity: rgba(255, 255, 255, 0.95);
+	--column-width: 42rem;
+	--column-margin-top: 4rem;
 }
 
 body {
-  min-height: 100vh;
-  margin: 0;
-  background-color: var(--primary-color);
-}
-
-body::before {
-  content: "";
-  width: 80vw;
-  height: 100vh;
-  position: absolute;
-  top: 0;
-  left: 10vw;
-  z-index: -1;
-  background: radial-gradient(
-    50% 50% at 50% 50%,
-    var(--pure-white) 0%,
-    rgba(255, 255, 255, 0) 100%
-  );
-  opacity: 0.05;
+	min-height: 100vh;
+	margin: 0;
+	background-color: var(--primary-color);
+	color: var(--text-color);
 }
 
 #svelte {
-  min-height: 100vh;
-  display: flex;
-  flex-direction: column;
+	min-height: 100vh;
+	display: flex;
+	flex-direction: column;
 }
 
 h1,
 h2,
 p {
-  font-weight: 400;
-  color: var(--heading-color);
+	font-weight: 400;
+	color: var(--heading-color);
 }
 
 p {
-  line-height: 1.5;
+	line-height: 1.5;
 }
 
 a {
-  color: var(--accent-color);
-  text-decoration: none;
+	color: var(--accent-color);
+	text-decoration: none;
 }
-
 a:hover {
-  text-decoration: underline;
+	text-decoration: underline;
 }
 
 h1 {
-  font-size: 2rem;
-  text-align: center;
+	font-size: 2rem;
+	margin: 1rem 0;
+}
+@media (min-width: 720px) {
+	h1 {
+		font-size: 2.4rem;
+	}
 }
 
 h2 {
-  font-size: 1rem;
+	font-size: 1.6rem;
+	margin: 1rem 0;
+}
+
+h3,
+h4,
+h5,
+h6 {
+	margin: 0.5rem 0;
+	font-weight: 400;
+	color: var(--heading-color);
+	font-size: 1rem;
+}
+
+h1 + h2,
+h2 + h3,
+h3 + h4,
+h4 + h5,
+h5 + h6 {
+	margin-top: 0;
+}
+
+ul {
+	margin: 1rem 0;
 }
 
 pre {
-  font-size: 16px;
-  font-family: var(--font-mono);
-  background-color: rgba(255, 255, 255, 0.45);
-  border-radius: 3px;
-  box-shadow: 2px 2px 6px rgb(255 255 255 / 25%);
-  padding: 0.5em;
-  overflow-x: auto;
-  color: var(--text-color);
+	font-size: 16px;
+	font-family: var(--font-mono);
+	background-color: rgba(255, 255, 255, 0.45);
+	border-radius: 3px;
+	box-shadow: 2px 2px 6px rgb(255 255 255 / 25%);
+	padding: 0.5em;
+	overflow-x: auto;
+	color: var(--text-color);
+	margin: 0.5rem 0;
 }
 
 input,
 button {
-  font-size: inherit;
-  font-family: inherit;
+	font-size: inherit;
+	font-family: inherit;
 }
 
 button:focus:not(:focus-visible) {
-  outline: none;
+	outline: none;
 }
 
-@media (min-width: 720px) {
-  h1 {
-    font-size: 2.4rem;
-  }
+:target {
+	scroll-margin-top: 80px;
 }
 
-:target {
-  scroll-margin-top: 80px;
+/* twoslash */
+.twoslash .twoslash-popup-container {
+	transform: translateY(2em);
+	white-space: pre-wrap;
+	margin-right: 32px;
+}
+.twoslash .twoslash-error > span:not(.twoslash-popup-container):not(:has(*)) {
+	min-width: 6px;
+	display: inline-block;
+}
+
+/*** markdown ***/
+:not(pre) > code {
+	padding: 0.1rem 0.4rem;
+	margin: 0 0.2rem;
+	background: #e5eef5;
+	position: relative;
+	border-radius: 0.3em;
+	white-space: nowrap;
+	color: #444;
+	-webkit-font-smoothing: initial;
+	transform: translateY(-2px);
+	display: inline-block;
+}
+
+blockquote {
+	padding: 0.5rem 2.4rem;
+	color: #09f;
+	border: 1px solid #40b3ff;
+	margin: 1.6rem 2.4rem 2.4rem;
+	border-radius: 0.4rem;
+}
+blockquote p {
+	color: #09f;
+}
+
+table {
+	margin: 0 0 2em;
+	width: 100%;
+	font-size: 1rem; /* var(--h5)は未定義なので1remに */
+}
+td,
+th {
+	text-align: left;
+	border-bottom: 1px solid rgba(0 0 0 / 0.1);
+	padding: 0.4rem 0.8rem 0.4rem 0;
+}
+
+/* custom container */
+.custom-block .custom-block-title {
+	font-weight: 600;
+	margin-bottom: -0.4rem;
+}
+
+.custom-block.danger,
+.custom-block.tip,
+.custom-block.warning {
+	padding: 0.1rem 1.5rem;
+	border-left-width: 4px;
+	border-left-style: solid;
+	margin: 1rem 0;
+}
+
+.custom-block.tip {
+	background-color: #f3f5f7;
+	border-color: #42b983;
+}
+
+.custom-block.warning {
+	background-color: rgba(255, 229, 100, 0.3);
+	border-color: #e7c000;
+	color: #6b5900;
+}
+.custom-block.warning .custom-block-title {
+	color: #b29400;
+}
+.custom-block.warning a {
+	color: #2c3e50;
+}
+
+.custom-block.danger {
+	background-color: #ffe6e6;
+	border-color: #c00;
+	color: #4d0000;
+}
+.custom-block.danger .custom-block-title {
+	color: #900;
+}
+.custom-block.danger a {
+	color: #2c3e50;
+}
+
+.custom-block.details {
+	display: block;
+	position: relative;
+	border-radius: 2px;
+	margin: 1.6em 0;
+	padding: 1.6em;
+	background-color: #eee;
+}
+.custom-block.details h4 {
+	margin-top: 0;
+}
+.custom-block.details figure:last-child,
+.custom-block.details p:last-child {
+	margin-bottom: 0;
+	padding-bottom: 0;
+}
+.custom-block.details summary {
+	outline: none;
+	cursor: pointer;
 }
diff --git a/docs-svelte-kit/src/lib/footer/Footer.svelte b/docs-svelte-kit/src/lib/footer/Footer.svelte
index 01b6ed2..6a7fb82 100644
--- a/docs-svelte-kit/src/lib/footer/Footer.svelte
+++ b/docs-svelte-kit/src/lib/footer/Footer.svelte
@@ -47,27 +47,25 @@
 				target="_blank"
 				rel="noopener noreferrer">Edit this page</a
 			>
-			<span>
-				<svg
-					xmlns="http://www.w3.org/2000/svg"
-					aria-hidden="true"
-					focusable="false"
-					x="0px"
-					y="0px"
-					viewBox="0 0 100 100"
-					width="15"
-					height="15"
-					class="icon outbound"
-					><path
-						fill="currentColor"
-						d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"
-					/>
-					<polygon
-						fill="currentColor"
-						points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"
-					/>
-				</svg>
-			</span>
+			<svg
+				xmlns="http://www.w3.org/2000/svg"
+				aria-hidden="true"
+				focusable="false"
+				x="0px"
+				y="0px"
+				viewBox="0 0 100 100"
+				width="15"
+				height="15"
+				class="icon outbound"
+				><path
+					fill="currentColor"
+					d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"
+				/>
+				<polygon
+					fill="currentColor"
+					points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"
+				/>
+			</svg>
 		</div>
 		{#if fileInfo.lastUpdated}
 			<div class="last-updated">
@@ -85,29 +83,34 @@
 		{/if}
 	</div>
 	<div class="footer-text">
-		<span
-			>This site was built with <a href="https://kit.svelte.dev/" target="_brank">SvelteKit</a
-			>.</span
-		>
+		<span>
+			This site was built with <a href="https://kit.svelte.dev/" target="_brank">SvelteKit</a>.
+		</span>
 	</div>
 </footer>
 
 <style>
 	.footer-tools {
 		width: 100%;
-		padding: 1rem;
+		padding: 0 1rem;
 		box-sizing: border-box;
 		display: flex;
 	}
+
+	.edit-link {
+		display: flex;
+		gap: 4px;
+	}
+
 	.footer-move {
 		border-top: 1px solid var(--background-without-opacity);
 		width: 100%;
-		padding: 1rem;
+		padding: 0 1rem;
 		box-sizing: border-box;
 		display: flex;
 	}
 	.footer-text {
-		padding: 1rem;
+		padding: 0 1rem 1rem 1rem;
 		display: flex;
 		flex-direction: column;
 		justify-content: center;
@@ -139,7 +142,7 @@
 		flex-direction: column;
 		justify-content: center;
 		align-items: center;
-		padding: 40px;
+		padding: 16px 0 0 0;
 	}
 
 	footer a {
@@ -148,7 +151,7 @@
 
 	@media (min-width: 480px) {
 		footer {
-			padding: 40px 0;
+			padding: 24px 0 0 0;
 		}
 	}
 </style>
diff --git a/docs-svelte-kit/src/lib/header/Header.svelte b/docs-svelte-kit/src/lib/header/Header.svelte
index 78af595..4e8d2a2 100644
--- a/docs-svelte-kit/src/lib/header/Header.svelte
+++ b/docs-svelte-kit/src/lib/header/Header.svelte
@@ -103,9 +103,9 @@
 		padding: 0.5em 2em;
 		position: fixed;
 		top: 0;
-		width: calc(100% - 4em);
+		width: 100vw;
 		z-index: 100;
-		background-color: white;
+		background-color: var(--primary-color);
 		box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
 	}
 
diff --git a/docs-svelte-kit/src/lib/sidemenu/UlMenu.svelte b/docs-svelte-kit/src/lib/sidemenu/UlMenu.svelte
index 3248bb5..c71888e 100644
--- a/docs-svelte-kit/src/lib/sidemenu/UlMenu.svelte
+++ b/docs-svelte-kit/src/lib/sidemenu/UlMenu.svelte
@@ -7,7 +7,7 @@
 </script>
 
 <ul class="sidebar-menu sidebar-menu--level{level}">
-	{#each children as item (item.id)}
+	{#each children as item (item.path || item.id || item.title)}
 		<li
 			class="sidebar-menu-item"
 			class:active={item.active || (item.path && isActive(item.path, $page))}
@@ -17,8 +17,9 @@
 					class="sidebar-menu-item-title"
 					class:active={item.active || (item.path && isActive(item.path, $page))}
 					href="{baseUrl}{item.path || `${stripBaseUrl($page.url.pathname)}#${item.id}`}"
-					>{item.title}</a
 				>
+					{item.title}
+				</a>
 			{:else}
 				<span class="sidebar-menu-item-title">{item.title}</span>
 			{/if}
diff --git a/docs-svelte-kit/src/reset.css b/docs-svelte-kit/src/reset.css
new file mode 100644
index 0000000..e235875
--- /dev/null
+++ b/docs-svelte-kit/src/reset.css
@@ -0,0 +1,104 @@
+*,
+*::before,
+*::after {
+	margin: 0;
+	padding: 0;
+	box-sizing: border-box;
+}
+:where([hidden]:not([hidden='until-found'])) {
+	display: none !important;
+}
+:where(html) {
+	-webkit-text-size-adjust: none;
+	color-scheme: dark light;
+	tab-size: 2;
+	scrollbar-gutter: stable;
+}
+:where(html:has(dialog:modal[open])) {
+	overflow: clip;
+}
+@media (prefers-reduced-motion: no-preference) {
+	:where(html:focus-within) {
+		scroll-behavior: smooth;
+	}
+}
+:where(body) {
+	line-height: 1.5;
+	font-family: system-ui, sans-serif;
+	-webkit-font-smoothing: antialiased;
+}
+:where(button) {
+	all: unset;
+}
+:where(input, button, textarea, select) {
+	font: inherit;
+	color: inherit;
+}
+:where(textarea) {
+	resize: vertical;
+	resize: block;
+}
+:where(button, label, select, summary, [role='button'], [role='option']) {
+	cursor: pointer;
+}
+:where(:disabled) {
+	cursor: not-allowed;
+}
+:where(label:has(> input:disabled), label:has(+ input:disabled)) {
+	cursor: not-allowed;
+}
+:where(a) {
+	color: inherit;
+	text-underline-offset: 0.2ex;
+}
+:where(ul, ol) {
+	list-style: none;
+}
+:where(img, svg, video, canvas, audio, iframe, embed, object) {
+	display: block;
+}
+:where(img, picture, svg, video) {
+	max-inline-size: 100%;
+	block-size: auto;
+}
+:where(p, h1, h2, h3, h4, h5, h6) {
+	overflow-wrap: break-word;
+}
+:where(h1, h2, h3) {
+	line-height: calc(1em + 0.5rem);
+	text-wrap: balance;
+}
+:where(hr) {
+	border: none;
+	border-block-start: 1px solid;
+	color: inherit;
+	block-size: 0;
+	overflow: visible;
+}
+:where(dialog) {
+	border: none;
+	background: none;
+	inset: unset;
+	max-width: unset;
+	max-height: unset;
+}
+:where(dialog:not([open])) {
+	display: none !important;
+}
+:where(:focus-visible) {
+	outline: 3px solid CanvasText;
+	box-shadow: 0 0 0 5px Canvas;
+	outline-offset: 1px;
+}
+:where(:focus-visible, :target) {
+	scroll-margin-block: 8vh;
+}
+:where(.visually-hidden:not(:focus-within, :active)) {
+	clip-path: inset(50%) !important;
+	height: 1px !important;
+	width: 1px !important;
+	overflow: hidden !important;
+	position: absolute !important;
+	white-space: nowrap !important;
+	border: 0 !important;
+}
diff --git a/docs-svelte-kit/src/routes/+layout.svelte b/docs-svelte-kit/src/routes/+layout.svelte
index 14f2f3e..eaa30bc 100644
--- a/docs-svelte-kit/src/routes/+layout.svelte
+++ b/docs-svelte-kit/src/routes/+layout.svelte
@@ -3,9 +3,9 @@
 	import SideMenu from '$lib/sidemenu/SideMenu.svelte';
 	import Footer from '$lib/footer/Footer.svelte';
 
+	import '../reset.css';
 	import '../app.css';
-	import '../site.css';
-	import { tocStore } from '$lib/utils';
+	import { tocStore } from '$lib/utils.js';
 
 	/** @type {import('./$types').PageData */
 	export let data;
@@ -49,6 +49,7 @@
 <style>
 	main {
 		margin-top: 64px;
+		min-height: calc(100vh - 180px);
 	}
 	main:not(.hidden-menu) {
 		padding-left: 20rem;
@@ -69,7 +70,7 @@
 		flex: 1;
 		display: flex;
 		flex-direction: column;
-		padding: 1rem;
+		padding: 1rem calc(1rem + 16px);
 		width: 100%;
 		max-width: 1024px;
 		margin: 0 auto;
diff --git a/docs-svelte-kit/src/site.css b/docs-svelte-kit/src/site.css
deleted file mode 100644
index d92d253..0000000
--- a/docs-svelte-kit/src/site.css
+++ /dev/null
@@ -1,157 +0,0 @@
-/* @import "prismjs/themes/prism"; */
-@import 'prismjs/themes/prism-tomorrow';
-@import '@shikijs/twoslash/style-rich.css';
-
-.twoslash .twoslash-popup-container {
-	transform: translateY(2em);
-	white-space: pre-wrap;
-	margin-right: 32px;
-}
-
-.twoslash .twoslash-error > span:not(.twoslash-popup-container):not(:has(*)) {
-	/*
-	Since elements with no content have a width of zero and no wavy line is displayed,
-	we specify a minimum width to display the wavy line.
-	e.g. https://sveltejs.github.io/eslint-plugin-svelte/rules/html-closing-bracket-new-line/
-	*/
-	min-width: 6px;
-	display: inline-block;
-}
-
-/* theme */
-:root {
-	--primary-color: #ffffff;
-	--secondary-color: #676778;
-	--tertiary-color: #edf0f8;
-	--background-without-opacity: rgba(255, 255, 255, 0.95);
-}
-
-/*** markdown ***/
-
-:not(pre) > code {
-	padding: 0.1rem 0.4rem 0;
-	margin: 0 0.2rem;
-	background: #e5eef5;
-	position: relative;
-	border-radius: 0.3em;
-	white-space: nowrap;
-	color: #444;
-	-webkit-font-smoothing: initial;
-}
-
-blockquote {
-	padding: 1rem;
-	color: #09f;
-	border: 1px solid #40b3ff;
-	margin: 1.6rem 2.4rem 2.4rem;
-	padding: 0.5rem 2.4rem;
-	border-radius: 0.4rem;
-}
-blockquote p {
-	color: #09f;
-}
-
-table {
-	margin: 0 0 2em;
-	width: 100%;
-	font-size: var(--h5);
-}
-td,
-th {
-	text-align: left;
-	border-bottom: 1px solid rgba(0 0 0 / 0.1);
-	padding: 0.4rem 0.8rem 0.4rem 0;
-}
-
-/* header */
-
-h3,
-h4,
-h5,
-h6 {
-	font-weight: 400;
-	color: var(--heading-color);
-}
-
-h2 {
-	font-size: 1.2rem;
-}
-h3,
-h4,
-h5,
-h6 {
-	font-size: 1rem;
-}
-
-/*** custom container ***/
-
-.custom-block .custom-block-title {
-	font-weight: 600;
-	margin-bottom: -0.4rem;
-}
-
-.custom-block.danger,
-.custom-block.tip,
-.custom-block.warning {
-	padding: 0.1rem 1.5rem;
-	border-left-width: 4px;
-	border-left-style: solid;
-	margin: 1rem 0;
-}
-
-.custom-block.tip {
-	background-color: #f3f5f7;
-	border-color: #42b983;
-}
-
-.custom-block.warning {
-	background-color: rgba(255, 229, 100, 0.3);
-	border-color: #e7c000;
-	color: #6b5900;
-}
-
-.custom-block.warning .custom-block-title {
-	color: #b29400;
-}
-
-.custom-block.warning a {
-	color: #2c3e50;
-}
-
-.custom-block.danger {
-	background-color: #ffe6e6;
-	border-color: #c00;
-	color: #4d0000;
-}
-
-.custom-block.danger .custom-block-title {
-	color: #900;
-}
-
-.custom-block.danger a {
-	color: #2c3e50;
-}
-
-.custom-block.details {
-	display: block;
-	position: relative;
-	border-radius: 2px;
-	margin: 1.6em 0;
-	padding: 1.6em;
-	background-color: #eee;
-}
-
-.custom-block.details h4 {
-	margin-top: 0;
-}
-
-.custom-block.details figure:last-child,
-.custom-block.details p:last-child {
-	margin-bottom: 0;
-	padding-bottom: 0;
-}
-
-.custom-block.details summary {
-	outline: none;
-	cursor: pointer;
-}
diff --git a/docs/README.md b/docs/README.md
index e7bea45..9f765d5 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -2,63 +2,30 @@
 title: 'eslint-plugin-svelte'
 ---
 
-# Introduction
+## Introduction
 
-`eslint-plugin-svelte` is the official [ESLint] plugin for [Svelte].  
-It provides many unique check rules by using the template AST.  
-You can check on the [Online DEMO](https://eslint-online-playground.netlify.app/#eslint-plugin-svelte%20with%20typescript).
+`eslint-plugin-svelte` is the official [ESLint](https://eslint.org/) plugin for [Svelte](https://svelte.dev/).  
+It leverages the AST generated by [svelte-eslint-parser](https://github.com/sveltejs/svelte-eslint-parser) to provide custom linting for Svelte.  
+Note that `eslint-plugin-svelte` and `svelte-eslint-parser` cannot be used alongside [eslint-plugin-svelte3](https://github.com/sveltejs/eslint-plugin-svelte3).
 
-> [!NOTE]
-> This document is in development.\
-> Please refer to the document for the version you are using.\
-> For example, <https://github.com/sveltejs/eslint-plugin-svelte/blob/eslint-plugin-svelte%402.46.0/README.md>
-> and <https://github.com/sveltejs/eslint-plugin-svelte/blob/eslint-plugin-svelte%402.46.0/docs>
-
-[![NPM license](https://img.shields.io/npm/l/eslint-plugin-svelte.svg)](https://www.npmjs.com/package/eslint-plugin-svelte)
-[![NPM version](https://img.shields.io/npm/v/eslint-plugin-svelte.svg)](https://www.npmjs.com/package/eslint-plugin-svelte)
-[![NPM downloads](https://img.shields.io/badge/dynamic/json.svg?label=downloads&colorB=green&suffix=/day&query=$.downloads&uri=https://api.npmjs.org//downloads/point/last-day/eslint-plugin-svelte&maxAge=3600)](http://www.npmtrends.com/eslint-plugin-svelte)
-[![NPM downloads](https://img.shields.io/npm/dw/eslint-plugin-svelte.svg)](http://www.npmtrends.com/eslint-plugin-svelte)
-[![NPM downloads](https://img.shields.io/npm/dm/eslint-plugin-svelte.svg)](http://www.npmtrends.com/eslint-plugin-svelte)
-[![NPM downloads](https://img.shields.io/npm/dy/eslint-plugin-svelte.svg)](http://www.npmtrends.com/eslint-plugin-svelte)
-[![NPM downloads](https://img.shields.io/npm/dt/eslint-plugin-svelte.svg)](http://www.npmtrends.com/eslint-plugin-svelte)
-[![Build Status](https://github.com/sveltejs/eslint-plugin-svelte/workflows/CI/badge.svg?branch=main)](https://github.com/sveltejs/eslint-plugin-svelte/actions?query=workflow%3ACI)
-
-[![type-coverage](https://img.shields.io/badge/dynamic/json.svg?label=type-coverage&prefix=%E2%89%A5&suffix=%&query=$.typeCoverage.atLeast&uri=https%3A%2F%2Fraw.githubusercontent.com%2Fsveltejs%2Feslint-plugin-svelte%2Fmain%2Fpackage.json)](https://github.com/plantain-00/type-coverage)
-[![Conventional Commits](https://img.shields.io/badge/conventional%20commits-1.0.0-yellow.svg)](https://conventionalcommits.org)
-[![Code Style: Prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier)
-[![changesets](https://img.shields.io/badge/maintained%20with-changesets-176de3.svg)](https://github.com/atlassian/changesets)
-
-## :name_badge: What is this plugin?
-
-[ESLint] plugin for [Svelte].  
-It provides many unique check rules using the AST generated by [svelte-eslint-parser].
-
-### ❗ Attention
-
-#### Cannot be used with eslint-plugin-svelte3
+See [User Guide](./user-guide.md).
 
-The [svelte-eslint-parser] and the `eslint-plugin-svelte` can not be used with the [eslint-plugin-svelte3].
+## Migration Guide
 
-[svelte-eslint-parser]: https://github.com/sveltejs/svelte-eslint-parser
-[eslint-plugin-svelte3]: https://github.com/sveltejs/eslint-plugin-svelte3
+If you’re migrating from `eslint-plugin-svelte` v1 or [`@ota-meshi/eslint-plugin-svelte`](https://www.npmjs.com/package/@ota-meshi/eslint-plugin-svelte), see the [migration guide](./migration.md).
 
-#### Experimental support for Svelte v5
+## Versioning Policy
 
-We are working on support for Svelte v5, but it is still an experimental feature. Please note that rules and features related to Svelte v5 may be changed or removed in minor versions without notice.
+This project follows [Semantic Versioning](https://semver.org/). Unlike [ESLint’s versioning policy](https://github.com/eslint/eslint#semantic-versioning-policy), new rules may be added to the recommended config in minor releases. If these rules cause unwanted warnings, you can disable them.
 
-## :book: Usage
+<!--DOCS_IGNORE_END-->
 
-See [User Guide](./user-guide.md).
-
-## :white_check_mark: Rules
+## Rules
 
 <!-- prettier-ignore-start -->
 See [Available Rules](./rules.md).
 <!-- prettier-ignore-end -->
 
-## :lock: License
-
-See the [LICENSE](https://github.com/sveltejs/eslint-plugin-svelte/blob/main/LICENSE) file for license rights and limitations (MIT).
+## License
 
-[svelte]: https://svelte.dev/
-[eslint]: https://eslint.org/
+See [LICENSE](https://github.com/sveltejs/eslint-plugin-svelte/blob/main/LICENSE) (MIT).
diff --git a/docs/migration.md b/docs/migration.md
index 10cd9b6..0acc972 100644
--- a/docs/migration.md
+++ b/docs/migration.md
@@ -62,3 +62,99 @@ Therefore, you need to replace the package name, and the presets, rules, and set
     +    "svelte": { ... }
       },
     ```
+
+## From `eslint-plugin-svelte` v2 To v3
+
+This section explains the necessary changes when upgrading from `eslint-plugin-svelte` v2 to v3.  
+v3 includes **support for ESLint Flat Config only**, **changes to the recommended rule set**, and other breaking changes.
+
+---
+
+## Breaking Changes
+
+### 1. **Minimum Node.js Version Requirement**
+
+v3 requires **one of the following Node.js versions**:
+
+- `^18.20.4`
+- `^20.18.0`
+- `>=22.10.0`
+
+### 2. **ESLint Flat Config Only**
+
+- `.eslintrc.js` and `.eslintrc.json` are **no longer supported**.
+- You must use **Flat Config (`eslint.config.js`)**.
+- See [README](README.md) for more details.
+
+### 3. **ESLint Version Requirement**
+
+- v3 requires **ESLint 8.57.1 or later** (including v9.x).
+
+### 4. **Changes to Recommended Rule Set**
+
+- The following rules are now included in `recommended`:
+  - `svelte/infinite-reactive-loop`
+  - `svelte/no-dom-manipulating`
+  - `svelte/no-dupe-on-directives`
+  - `svelte/no-reactive-reassign`
+  - `svelte/require-event-dispatcher-types`
+  - Many others (See [Changelog](https://github.com/sveltejs/eslint-plugin-svelte/releases/tag/eslint-plugin-svelte%403.0.0-next.16) for more details)
+- `svelte/valid-compile` has been **removed** from `recommended`.
+
+### 5. **Deprecated Rules**
+
+- `svelte/no-dynamic-slot-name` is **deprecated**.
+- `svelte/no-goto-without-base` is **deprecated** and replaced with `svelte/no-navigation-without-base`.
+
+---
+
+## New Features & Improvements
+
+### 1. **Support for Svelte 5**
+
+- Rules such as `no-not-function-handler` and `valid-prop-names-in-kit-pages` now support **Svelte 5**.
+
+### 2. **New Rules**
+
+- `consistent-selector-style`: Enforce consistent selector styles.
+- `no-useless-children-snippet`: Prevent unnecessary `{@children}` usage.
+- `prefer-const`: Prefer `const` over `let`.
+- `no-navigation-without-base`: Ensure proper usage of `goto()`.
+
+---
+
+## Migration Steps
+
+### 1. **Upgrade Package**
+
+```sh
+npm install eslint-plugin-svelte@3
+```
+
+### 2. **Check Node.js Version**
+
+```sh
+node -v
+```
+
+- Ensure it is `v18.20.4` or later.
+
+### 3. **Check ESLint Version**
+
+```sh
+npx eslint -v
+```
+
+- Ensure it is `8.57.1` or later (or `9.x`).
+
+### 4. **Use Flat Config (`eslint.config.js`)**
+
+- Remove `.eslintrc.js` and migrate to `eslint.config.js`.
+
+### 5. **Apply the Updated Recommended Rules**
+
+- If using `recommended`, check the impact of newly added rules.
+
+### 6. **Replace Deprecated Rules**
+
+- Replace `no-goto-without-base` with `no-navigation-without-base`.
diff --git a/docs/rules.md b/docs/rules.md
index 5e509b0..7d2834a 100644
--- a/docs/rules.md
+++ b/docs/rules.md
@@ -32,6 +32,7 @@ These rules relate to possible syntax or logic errors in Svelte code:
 | [svelte/require-store-callbacks-use-set-param](./rules/require-store-callbacks-use-set-param.md) | store callbacks must use `set` param                                                                                                   |                |
 | [svelte/require-store-reactive-access](./rules/require-store-reactive-access.md)                 | disallow to use of the store itself as an operand. Need to use $ prefix or get function.                                               | :star::wrench: |
 | [svelte/valid-compile](./rules/valid-compile.md)                                                 | disallow warnings when compiling.                                                                                                      |                |
+| [svelte/valid-style-parse](./rules/valid-style-parse.md)                                         | require valid style element parsing                                                                                                    |                |
 
 ## Security Vulnerability
 
@@ -67,7 +68,7 @@ These rules relate to better ways of doing things to help you avoid problems:
 | [svelte/require-each-key](./rules/require-each-key.md)                                   | require keyed `{#each}` block                                                                                                             | :star:         |
 | [svelte/require-event-dispatcher-types](./rules/require-event-dispatcher-types.md)       | require type parameters for `createEventDispatcher`                                                                                       | :star:         |
 | [svelte/require-optimized-style-attribute](./rules/require-optimized-style-attribute.md) | require style attributes that can be optimized                                                                                            |                |
-| [svelte/require-stores-init](./rules/require-stores-init.md)                             | require initial value in store                                                                                                            | :star:         |
+| [svelte/require-stores-init](./rules/require-stores-init.md)                             | require initial value in store                                                                                                            |                |
 | [svelte/valid-each-key](./rules/valid-each-key.md)                                       | enforce keys to use variables defined in the `{#each}` block                                                                              | :star:         |
 
 ## Stylistic Issues
diff --git a/docs/rules/no-export-load-in-svelte-module-in-kit-pages.md b/docs/rules/no-export-load-in-svelte-module-in-kit-pages.md
index 5c6ccab..fc13f85 100644
--- a/docs/rules/no-export-load-in-svelte-module-in-kit-pages.md
+++ b/docs/rules/no-export-load-in-svelte-module-in-kit-pages.md
@@ -34,7 +34,7 @@ And the API has changed.
 
 ## :wrench: Options
 
-Nothing. But if you are not using the default routes folder, please set configuration according to the [user guide](../user-guide.md#settings-svelte-kit).
+Nothing. But if you are not using the default routes folder, please set configuration according to the [user guide](../user-guide.md#settings-svelte).
 
 ## :books: Further Reading
 
diff --git a/docs/rules/no-inner-declarations.md b/docs/rules/no-inner-declarations.md
index 43d69f2..50cff3e 100644
--- a/docs/rules/no-inner-declarations.md
+++ b/docs/rules/no-inner-declarations.md
@@ -48,7 +48,9 @@ This rule supports [svelte-eslint-parser]'s AST.
   "svelte/no-inner-declarations": [
     "error",
     "functions", // or "both"
-    { "blockScopedFunctions": "allow" }
+    {
+      "blockScopedFunctions": "allow" // or "disallow"
+    }
   ]
 }
 ```
diff --git a/docs/rules/prefer-class-directive.md b/docs/rules/prefer-class-directive.md
index ab68bb5..5b5c6a1 100644
--- a/docs/rules/prefer-class-directive.md
+++ b/docs/rules/prefer-class-directive.md
@@ -41,7 +41,7 @@ You cannot enforce this style by using [prettier-plugin-svelte]. That is, this r
 
 ```json
 {
-  "svelte/html-quotes": [
+  "svelte/prefer-class-directive": [
     "error",
     {
       "prefer": "empty" // or "always"
diff --git a/docs/rules/prefer-const.md b/docs/rules/prefer-const.md
index a6ad021..8029ea8 100644
--- a/docs/rules/prefer-const.md
+++ b/docs/rules/prefer-const.md
@@ -14,7 +14,7 @@ since: 'v3.0.0-next.6'
 
 ## :book: Rule Details
 
-This rule reports the same as the base ESLint `prefer-const` rule, except that ignores Svelte reactive values such as `$derived` and `$props`. If this rule is active, make sure to disable the base `prefer-const` rule, as it will conflict with this rule.
+This rule reports the same as the base ESLint `prefer-const` rule, except that ignores Svelte reactive values such as `$derived` and `$props` as default. If this rule is active, make sure to disable the base `prefer-const` rule, as it will conflict with this rule.
 
 <!--eslint-skip-->
 
@@ -46,7 +46,8 @@ This rule reports the same as the base ESLint `prefer-const` rule, except that i
     "error",
     {
       "destructuring": "any",
-      "ignoreReadonly": true
+      "ignoreReadonly": true,
+      "excludedRunes": ["$props", "$derived"]
     }
   ]
 }
@@ -56,6 +57,7 @@ This rule reports the same as the base ESLint `prefer-const` rule, except that i
   - `any` (default): if any variables in destructuring should be const, this rule warns for those variables.
   - `all`: if all variables in destructuring should be const, this rule warns the variables. Otherwise, ignores them.
 - `ignoreReadonly`: If `true`, this rule will ignore variables that are read between the declaration and the _first_ assignment.
+- `excludedRunes`: An array of rune names that should be ignored. Even if a rune is declared with `let`, it will still be ignored.
 
 ## :books: Further Reading
 
diff --git a/docs/rules/require-each-key.md b/docs/rules/require-each-key.md
index af8186b..cd0069c 100644
--- a/docs/rules/require-each-key.md
+++ b/docs/rules/require-each-key.md
@@ -44,7 +44,7 @@ Nothing.
 
 ## :books: Further Reading
 
-- [Svelte - Tutorial > 4. Logic / Keyed each blocks](https://svelte.dev/tutorial/keyed-each-blocks)
+- [Svelte - Tutorial > 4. Logic / Keyed each blocks](https://svelte.dev/tutorial/svelte/keyed-each-blocks)
 
 ## :rocket: Version
 
diff --git a/docs/rules/require-stores-init.md b/docs/rules/require-stores-init.md
index 177dd3c..13dcc99 100644
--- a/docs/rules/require-stores-init.md
+++ b/docs/rules/require-stores-init.md
@@ -10,8 +10,6 @@ since: 'v2.5.0'
 
 > require initial value in store
 
-- :gear: This rule is included in `"plugin:svelte/recommended"`.
-
 ## :book: Rule Details
 
 This rule is aimed to enforce initial values when initializing the Svelte stores.
diff --git a/docs/rules/valid-compile.md b/docs/rules/valid-compile.md
index 567ad6c..866d2d9 100644
--- a/docs/rules/valid-compile.md
+++ b/docs/rules/valid-compile.md
@@ -50,7 +50,7 @@ export default [
 ];
 ```
 
-See also [User Guide > Specify `svelte.config.js`](../user-guide.md#specify-svelte-config-js)
+See also [User Guide > Configuration](../user-guide.md#configuration)
 
 #### warningFilter
 
diff --git a/docs/rules/valid-prop-names-in-kit-pages.md b/docs/rules/valid-prop-names-in-kit-pages.md
index 7162f4b..3f3323c 100644
--- a/docs/rules/valid-prop-names-in-kit-pages.md
+++ b/docs/rules/valid-prop-names-in-kit-pages.md
@@ -41,7 +41,7 @@ At SvelteKit v1.0.0-next.405, instead of having multiple props corresponding to
 
 ## :wrench: Options
 
-Nothing. But if use are using not default routes folder, please set configuration according to the [user guide](../user-guide.md#settings-svelte-kit).
+Nothing. But if use are using not default routes folder, please set configuration according to the [user guide](../user-guide.md#settings-svelte).
 
 ## :books: Further Reading
 
diff --git a/docs/rules/valid-style-parse.md b/docs/rules/valid-style-parse.md
new file mode 100644
index 0000000..5e203ba
--- /dev/null
+++ b/docs/rules/valid-style-parse.md
@@ -0,0 +1,81 @@
+---
+pageClass: 'rule-details'
+sidebarDepth: 0
+title: 'svelte/valid-style-parse'
+description: 'require valid style element parsing'
+since: 'v3.0.0'
+---
+
+# svelte/valid-style-parse
+
+> require valid style element parsing
+
+## :book: Rule Details
+
+This rule reports issues with parsing of the `<style>` element by the svelte-eslint-parser.
+
+<!--eslint-skip-->
+
+```svelte
+<script>
+  /* eslint svelte/valid-style-parse: ["error"] */
+</script>
+
+<!-- ✓ GOOD -->
+<style>
+  .class {
+    font-weight: bold;
+  }
+</style>
+```
+
+```svelte
+<script>
+  /* eslint svelte/valid-style-parse: ["error"] */
+</script>
+
+<!-- ✓ GOOD -->
+<style lang="scss">
+  .class {
+    font-weight: bold;
+  }
+</style>
+```
+
+```svelte
+<script>
+  /* eslint svelte/valid-style-parse: ["error"] */
+</script>
+
+<!-- ✗ BAD -->
+<style>
+  .class
+    font-weight: bold;
+</style>
+```
+
+```svelte
+<script>
+  /* eslint svelte/valid-style-parse: ["error"] */
+</script>
+
+<!-- ✗ BAD -->
+<style lang="unknown">
+  .class {
+    font-weight: bold;
+  }
+</style>
+```
+
+## :wrench: Options
+
+Nothing.
+
+## :rocket: Version
+
+This rule was introduced in eslint-plugin-svelte v3.0.0
+
+## :mag: Implementation
+
+- [Rule source](https://github.com/sveltejs/eslint-plugin-svelte/blob/main/packages/eslint-plugin-svelte/src/rules/valid-style-parse.ts)
+- [Test source](https://github.com/sveltejs/eslint-plugin-svelte/blob/main/packages/eslint-plugin-svelte/tests/src/rules/valid-style-parse.ts)
diff --git a/docs/user-guide.md b/docs/user-guide.md
index eaec310..0eba2e2 100644
--- a/docs/user-guide.md
+++ b/docs/user-guide.md
@@ -1,177 +1,175 @@
 # User Guide
 
-> [!NOTE]
-> This document is in development.\
-> Please refer to the document for the version you are using.\
-> For example, <https://github.com/sveltejs/eslint-plugin-svelte/blob/eslint-plugin-svelte%402.46.0/docs/user-guide.md>
+<!--USAGE_GUIDE_START-->
 
-## :cd: Installation
+## Installation
 
 ```bash
-npm install --save-dev eslint eslint-plugin-svelte svelte
+npm install --save-dev svelte eslint eslint-plugin-svelte globals
 ```
 
-::: tip Requirements
-
-- ESLint v8.57.1, v9.0.0 and above
-- Node.js v18.20.4, v20.18.0, v22.10.0 and above
-
-:::
+> [!NOTE]
+>
+> **Requirements:**
+>
+> - ESLint v8.57.1, v9.0.0, and above
+> - Node.js v18.20.4, v20.18.0, v22.10.0, and above
 
-## :book: Usage
+## Usage
 
-<!--USAGE_GUIDE_START-->
+Use the `eslint.config.js` file to configure rules. For more details, see the [ESLint documentation](https://eslint.org/docs/latest/use/configure/configuration-files-new).
 
 ### Configuration
 
-Use `eslint.config.js` file to configure rules. See also: <https://eslint.org/docs/latest/use/configure/configuration-files-new>.
-
-Example **eslint.config.js**:
+#### JavaScript project
 
 ```js
-import eslintPluginSvelte from 'eslint-plugin-svelte';
-export default [
-  // add more generic rule sets here, such as:
-  // js.configs.recommended,
-  ...eslintPluginSvelte.configs.recommended,
-  {
-    rules: {
-      // override/add rules settings here, such as:
-      // 'svelte/rule-name': 'error'
-    }
-  }
-];
-```
-
-This plugin provides configs:
-
-- `eslintPluginSvelte.configs.base` ... Configuration to enable correct Svelte parsing.
-- `eslintPluginSvelte.configs.recommended` ... Above, plus rules to prevent errors or unintended behavior.
-- `eslintPluginSvelte.configs.prettier` ... Turns off rules that may conflict with [Prettier](https://prettier.io/) (You still need to configure prettier to work with svelte yourself, for example by using [prettier-plugin-svelte](https://github.com/sveltejs/prettier-plugin-svelte).).
-- `eslintPluginSvelte.configs.all` ... All rules. This configuration is not recommended for production use because it changes with every minor and major version of `eslint-plugin-svelte`. Use it at your own risk.
-
-See [the rule list](./rules.md) to get the `rules` that this plugin provides.
-
-#### Parser Configuration
-
-If you have specified a parser, you need to configure a parser for `.svelte`.
-
-For example, if you are using the `"@typescript-eslint/parser"`, and if you want to use TypeScript in `<script>` of `.svelte`, you need to add more `parserOptions` configuration.
+// eslint.config.js
+import js from '@eslint/js';
+import svelte from 'eslint-plugin-svelte';
+import globals from 'globals';
+import svelteConfig from './svelte.config.js';
 
-```js
-import eslintPluginSvelte from 'eslint-plugin-svelte';
-import * as svelteParser from 'svelte-eslint-parser';
-import * as typescriptParser from '@typescript-eslint/parser';
+/** @type {import('eslint').Linter.Config[]} */
 export default [
-  ...js.configs.recommended,
-  ...eslintPluginSvelte.configs.recommended,
+  js.configs.recommended,
+  ...svelte.configs.recommended,
   {
-    files: ['**/*.svelte'],
     languageOptions: {
-      parser: svelteParser,
-      parserOptions: {
-        parser: typescriptParser,
-        project: './path/to/your/tsconfig.json',
-        extraFileExtensions: ['.svelte']
+      globals: {
+        ...globals.browser,
+        ...globals.node // Add this if you are using SvelteKit in non-SPA mode
       }
     }
-  }
-];
-```
-
-If you have a mix of TypeScript and JavaScript in your project, use a multiple parser configuration.
-
-```js
-import eslintPluginSvelte from 'eslint-plugin-svelte';
-import * as svelteParser from 'svelte-eslint-parser';
-import * as typescriptParser from '@typescript-eslint/parser';
-import espree from 'espree';
-export default [
-  ...js.configs.recommended,
-  ...eslintPluginSvelte.configs.recommended,
+  },
   {
-    files: ['**/*.svelte'],
+    files: ['**/*.svelte', '**/*.svelte.js'],
     languageOptions: {
-      parser: svelteParser,
       parserOptions: {
-        parser: {
-          // Specify a parser for each lang.
-          ts: typescriptParser,
-          js: espree,
-          typescript: typescriptParser
-        },
-        project: './path/to/your/tsconfig.json',
-        extraFileExtensions: ['.svelte']
+        // We recommend importing and specifying svelte.config.js.
+        // By doing so, some rules in eslint-plugin-svelte will automatically read the configuration and adjust their behavior accordingly.
+        // While certain Svelte settings may be statically loaded from svelte.config.js even if you don’t specify it,
+        // explicitly specifying it ensures better compatibility and functionality.
+        svelteConfig
       }
     }
+  },
+  {
+    rules: {
+      // Override or add rule settings here, such as:
+      // 'svelte/rule-name': 'error'
+    }
   }
 ];
 ```
 
-See also <https://github.com/sveltejs/svelte-eslint-parser#readme>.
-
-::: warning ❗ Attention
-
-The TypeScript parser uses a singleton internally and it will only use the
-options given to it when it was first initialized. If trying to change the
-options for a different file or override, the parser will simply ignore the new
-options (which may result in an error). See
-[typescript-eslint/typescript-eslint#6778](https://github.com/typescript-eslint/typescript-eslint/issues/6778)
-for some context.
-
-:::
-
-#### Specify `svelte.config.js`
+#### TypeScript project
 
-If you are using `eslint.config.js`, we recommend that you import and specify `svelte.config.js`.
-By specifying it, some rules of `eslint-plugin-svelte` will read it and try to behave well for you by default.
-Some Svelte configurations will be statically loaded from `svelte.config.js` even if you don't specify it, but you need to specify it to make it work better.
-
-Example **eslint.config.js**:
+```shell
+npm install --save-dev typescript-eslint
+```
 
 ```js
-import eslintPluginSvelte from 'eslint-plugin-svelte';
+// eslint.config.js
+import js from '@eslint/js';
+import svelte from 'eslint-plugin-svelte';
+import globals from 'globals';
+import ts from 'typescript-eslint';
 import svelteConfig from './svelte.config.js';
-export default [
-  ...eslintPluginSvelte.configs.recommended,
+
+export default ts.config(
+  js.configs.recommended,
+  ...ts.configs.recommended,
+  ...svelte.configs.recommended,
+  {
+    languageOptions: {
+      globals: {
+        ...globals.browser,
+        ...globals.node
+      }
+    }
+  },
   {
-    files: [
-      '**/*.svelte',
-      '*.svelte'
-      // Add more files if you need.
-      // '**/*.svelte.ts', '*.svelte.ts', '**/*.svelte.js', '*.svelte.js',
-    ],
+    files: ['**/*.svelte', '**/*.svelte.ts', '**/*.svelte.js'],
+    // See more details at: https://typescript-eslint.io/packages/parser/
     languageOptions: {
       parserOptions: {
-        // Specify the `svelte.config.js`.
+        projectService: true,
+        extraFileExtensions: ['.svelte'], // Add support for additional file extensions, such as .svelte
+        parser: ts.parser,
+        // Specify a parser for each language, if needed:
+        // parser: {
+        //   ts: ts.parser,
+        //   js: espree,    // Use espree for .js files (add: import espree from 'espree')
+        //   typescript: ts.parser
+        // },
+
+        // We recommend importing and specifying svelte.config.js.
+        // By doing so, some rules in eslint-plugin-svelte will automatically read the configuration and adjust their behavior accordingly.
+        // While certain Svelte settings may be statically loaded from svelte.config.js even if you don’t specify it,
+        // explicitly specifying it ensures better compatibility and functionality.
         svelteConfig
       }
     }
+  },
+  {
+    rules: {
+      // Override or add rule settings here, such as:
+      // 'svelte/rule-name': 'error'
+    }
   }
-];
+);
 ```
 
-#### settings.svelte
+> [!WARNING]
+> The TypeScript parser uses a singleton internally, meaning it only respects the options provided during its initial initialization.
+> If you try to change the options for a different file or override them later, the parser will ignore the new options, which may lead to errors.
+> For more context, see [typescript-eslint/typescript-eslint#6778](https://github.com/typescript-eslint/typescript-eslint/issues/6778).
+
+### Available Configurations
+
+This plugin provides the following configurations:
+
+- **`eslintPluginSvelte.configs.base`** ... Enables correct Svelte parsing.
+- **`eslintPluginSvelte.configs.recommended`** ... Includes `base` configuration, plus rules to prevent errors or unintended behavior.
+- **`eslintPluginSvelte.configs.prettier`** ... Disables rules that may conflict with [Prettier](https://prettier.io/). You still need to configure Prettier to work with Svelte manually, for example, by using [prettier-plugin-svelte](https://github.com/sveltejs/prettier-plugin-svelte).
+- **`eslintPluginSvelte.configs.all`** ... Includes all available rules. **Note:** This configuration is not recommended for production use, as it changes with every minor and major version of `eslint-plugin-svelte`. Use at your own risk.
+
+For more details, see [the rule list](./rules.md) to explore the rules provided by this plugin.
 
-You can change the behavior of this plugin with some settings.
+### settings.svelte
 
-e.g.
+You can customize the behavior of this plugin using specific settings.
 
 ```js
+// eslint.config.js
 export default [
   // ...
   {
     settings: {
       svelte: {
+        // Specifies an array of rules to ignore reports within the template.
+        // For example, use this to disable rules in the template that may produce unavoidable false positives.
         ignoreWarnings: [
           '@typescript-eslint/no-unsafe-assignment',
           '@typescript-eslint/no-unsafe-member-access'
         ],
+        // Specifies options for Svelte compilation.
+        // This affects rules that rely on Svelte compilation,
+        // such as svelte/valid-compile and svelte/no-unused-svelte-ignore.
+        // Note that this setting does not impact ESLint’s custom parser.
         compileOptions: {
+          // Specifies options related to PostCSS. You can disable the PostCSS processing by setting it to false.
           postcss: {
+            // Specifies the path to the directory that contains the PostCSS configuration.
             configFilePath: './path/to/my/postcss.config.js'
           }
         },
+        // Even if settings.svelte.kit is not specified, the rules will attempt to load information from svelte.config.js.
+        // However, if the default behavior does not work as expected, you should specify settings.svelte.kit explicitly.
+        // If you are using SvelteKit with a non-default configuration, you need to set the following options.
+        // The schema is a subset of SvelteKit’s configuration, so refer to the SvelteKit documentation for more details.
+        // https://svelte.dev/docs/kit/configuration
         kit: {
           files: {
             routes: 'src/routes'
@@ -184,59 +182,11 @@ export default [
 ];
 ```
 
-#### settings.svelte.ignoreWarnings
-
-Specifies an array of rules that ignore reports in the template.  
-For example, set rules on the template that cannot avoid false positives.
-
-#### settings.svelte.compileOptions
-
-Specifies options for Svelte compile. Effects rules that use Svelte compile. The target rules are [svelte/valid-compile](./rules/valid-compile.md) and [svelte/no-unused-svelte-ignore](./rules/no-unused-svelte-ignore.md). **Note that it has no effect on ESLint's custom parser**.
-
-- `postcss` ... Specifies options related to PostCSS. You can disable the PostCSS process by specifying `false`.
-  - `configFilePath` ... Specifies the path of the directory containing the PostCSS configuration.
-
-#### settings.svelte.kit
-
-::: warning
-
-Even if you don't specify `settings.svelte.kit`, the rules will try to load information from `svelte.config.js`, so specify `settings.svelte.kit` if the default doesn't work.
-
-:::
-
-If you use SvelteKit with not default configuration, you need to set below configurations.
-The schema is subset of SvelteKit's configuration.
-Therefore please check [SvelteKit docs](https://kit.svelte.dev/docs/configuration) for more details.
-
-e.g.
-
-```js
-export default [
-  // ...
-  {
-    settings: {
-      svelte: {
-        kit: {
-          files: {
-            routes: 'src/routes'
-          }
-        }
-      }
-    }
-  }
-  // ...
-];
-```
-
-## :computer: Editor Integrations
+## Editor Integrations
 
-### Visual Studio Code
-
-Use the [dbaeumer.vscode-eslint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) extension that Microsoft provides officially.
-
-You have to configure the `eslint.validate` option of the extension to check `.svelte` files, because the extension targets only `*.js` or `*.jsx` files by default.
-
-Example **.vscode/settings.json**:
+**Visual Studio Code**  
+Install [dbaeumer.vscode-eslint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint).  
+Configure `.svelte` files in `.vscode/settings.json`:
 
 ```json
 {
@@ -246,11 +196,7 @@ Example **.vscode/settings.json**:
 
 <!--USAGE_GUIDE_END-->
 
-## :question: FAQ
-
-### Parsing the `.svelte` file fails
-
-You should check the [parser configuration](#parser-configuration).
+## FAQ
 
 ### You're using TypeScript and the imported `*.svelte` component types cannot be resolved or appear to be
 
diff --git a/package.json b/package.json
index f2761f2..1551d4a 100644
--- a/package.json
+++ b/package.json
@@ -4,7 +4,7 @@
   "private": true,
   "license": "MIT",
   "funding": "https://github.com/sponsors/ota-meshi",
-  "packageManager": "pnpm@9.15.5",
+  "packageManager": "pnpm@9.15.6",
   "scripts": {
     "prerelease": "cd packages/eslint-plugin-svelte && pnpm clean && pnpm run build && cd ../.. && cp README.md packages/eslint-plugin-svelte",
     "release": "changeset publish",
@@ -24,7 +24,7 @@
     "@typescript-eslint/parser": "^8.16.0",
     "c8": "^10.1.2",
     "env-cmd": "^10.1.0",
-    "eslint": "~9.20.0",
+    "eslint": "~9.21.0",
     "eslint-config-prettier": "^10.0.0",
     "eslint-formatter-friendly": "^7.0.0",
     "eslint-plugin-eslint-plugin": "^6.3.2",
diff --git a/packages/eslint-plugin-svelte/CHANGELOG.md b/packages/eslint-plugin-svelte/CHANGELOG.md
index 4d95e3c..d50af00 100644
--- a/packages/eslint-plugin-svelte/CHANGELOG.md
+++ b/packages/eslint-plugin-svelte/CHANGELOG.md
@@ -1,5 +1,157 @@
 # eslint-plugin-svelte
 
+## 3.0.3
+
+### Patch Changes
+
+- [#1115](https://github.com/sveltejs/eslint-plugin-svelte/pull/1115) [`7f756b8`](https://github.com/sveltejs/eslint-plugin-svelte/commit/7f756b8535818008742eead569ebf03065db776b) Thanks [@baseballyama](https://github.com/baseballyama)! - fix: align required Node version with ESLint
+
+## 3.0.2
+
+### Patch Changes
+
+- [#1100](https://github.com/sveltejs/eslint-plugin-svelte/pull/1100) [`1358d89`](https://github.com/sveltejs/eslint-plugin-svelte/commit/1358d89206e9cf57faf5789d246ed99489f1685b) Thanks [@baseballyama](https://github.com/baseballyama)! - fix: handle `<script module>` in `valid-prop-names-in-kit-pages` rule
+
+## 3.0.1
+
+### Patch Changes
+
+- [#1091](https://github.com/sveltejs/eslint-plugin-svelte/pull/1091) [`83da078`](https://github.com/sveltejs/eslint-plugin-svelte/commit/83da0784e93fe148579de6fcd665ed94da76411d) Thanks [@ottomated](https://github.com/ottomated)! - fix: Don't remove mustache'd string literals if they contain curly braces
+
+## 3.0.0
+
+### Major Changes
+
+- [#937](https://github.com/sveltejs/eslint-plugin-svelte/pull/937) [`729394e`](https://github.com/sveltejs/eslint-plugin-svelte/commit/729394e34d2d6f51e00c89b67a40d0f9192260b4) Thanks [@ota-meshi](https://github.com/ota-meshi)! - feat!: drop support for old eslint
+
+- [#1033](https://github.com/sveltejs/eslint-plugin-svelte/pull/1033) [`3bfcc31`](https://github.com/sveltejs/eslint-plugin-svelte/commit/3bfcc31e0f2d127c7a1cb838c4c57125c30109ea) Thanks [@baseballyama](https://github.com/baseballyama)! - **Enabled in recommended config**:
+
+  - `svelte/infinite-reactive-loop`
+  - `svelte/no-dom-manipulating`
+  - `svelte/no-dupe-on-directives`
+  - `svelte/no-dupe-use-directives`
+  - `svelte/no-export-load-in-svelte-module-in-kit-pages`
+  - `svelte/no-immutable-reactive-statements`
+  - `svelte/no-inspect`
+  - `svelte/no-raw-special-elements`
+  - `svelte/no-reactive-functions`
+  - `svelte/no-reactive-literals`
+  - `svelte/no-reactive-reassign`
+  - `svelte/no-store-async`
+  - `svelte/no-svelte-internal`
+  - `svelte/no-useless-children-snippet`
+  - `svelte/no-useless-mustaches`
+  - `svelte/require-each-key`
+  - `svelte/require-event-dispatcher-types`
+  - `svelte/require-store-reactive-access`
+  - `svelte/require-stores-init`
+  - `svelte/valid-each-key`
+  - `svelte/valid-prop-names-in-kit-pages`
+
+  **Removed from recommended config**:
+
+  - `svelte/valid-compile`
+
+  This update introduces breaking changes due to newly enabled rules.
+
+- [#1086](https://github.com/sveltejs/eslint-plugin-svelte/pull/1086) [`1c679b5`](https://github.com/sveltejs/eslint-plugin-svelte/commit/1c679b50f310040257b89e4e03d3a88764fd7b28) Thanks [@baseballyama](https://github.com/baseballyama)! - breaking: remove `require-stores-init` from recommended rules
+
+- [#1043](https://github.com/sveltejs/eslint-plugin-svelte/pull/1043) [`778427e`](https://github.com/sveltejs/eslint-plugin-svelte/commit/778427e8bd1a015247dd7f19642e2c6ced0891a8) Thanks [@ota-meshi](https://github.com/ota-meshi)! - feat: add `*.svelte.{js,ts}` config to base config
+
+- [#900](https://github.com/sveltejs/eslint-plugin-svelte/pull/900) [`4759b47`](https://github.com/sveltejs/eslint-plugin-svelte/commit/4759b47b195abee605a0597360fc9fc4c6d95f68) Thanks [@marekdedic](https://github.com/marekdedic)! - breaking: deprecated the no-goto-without-base rule
+
+- [#885](https://github.com/sveltejs/eslint-plugin-svelte/pull/885) [`ce2ffad`](https://github.com/sveltejs/eslint-plugin-svelte/commit/ce2ffad105b1c6ed2df02a9c2b84f3b654d99ad5) Thanks [@ota-meshi](https://github.com/ota-meshi)! - feat!: drop support for old node versions (<18, 19, 21)
+
+- [#1011](https://github.com/sveltejs/eslint-plugin-svelte/pull/1011) [`7596287`](https://github.com/sveltejs/eslint-plugin-svelte/commit/7596287c9d1a0a31c90e23875f6b7beab20747f1) Thanks [@baseballyama](https://github.com/baseballyama)! - breaking: deprecate the `svelte/no-dynamic-slot-name` rule
+
+- [#930](https://github.com/sveltejs/eslint-plugin-svelte/pull/930) [`eae1b4f`](https://github.com/sveltejs/eslint-plugin-svelte/commit/eae1b4fcbfbaec926cfa63a5d08eafcb2238bf82) Thanks [@ota-meshi](https://github.com/ota-meshi)! - feat!: upgrade svelte-eslint-parser to v1
+
+- [#982](https://github.com/sveltejs/eslint-plugin-svelte/pull/982) [`04fc429`](https://github.com/sveltejs/eslint-plugin-svelte/commit/04fc4292ef68134691ac1808fd92688bd9982d37) Thanks [@baseballyama](https://github.com/baseballyama)! - feat!: Updated the `html-self-closing` rule to follow Svelte5
+
+- [#932](https://github.com/sveltejs/eslint-plugin-svelte/pull/932) [`b136ab4`](https://github.com/sveltejs/eslint-plugin-svelte/commit/b136ab4e54d8ff38f6ba7f49e1209be14dd18b0b) Thanks [@ota-meshi](https://github.com/ota-meshi)! - feat!: change the plugin to an ESM-only package
+
+### Minor Changes
+
+- [#980](https://github.com/sveltejs/eslint-plugin-svelte/pull/980) [`0b28198`](https://github.com/sveltejs/eslint-plugin-svelte/commit/0b28198edd78513e5efc4cfb45e8f1120148435e) Thanks [@baseballyama](https://github.com/baseballyama)! - feat: Implement util to conditionally run lint based on Svelte version and SvelteKit routes etc
+
+- [#1013](https://github.com/sveltejs/eslint-plugin-svelte/pull/1013) [`0ef0f99`](https://github.com/sveltejs/eslint-plugin-svelte/commit/0ef0f99e1781e0453598393b846e63bd159c215d) Thanks [@baseballyama](https://github.com/baseballyama)! - feat: add Svelte 5 support to `no-not-function-handler`
+
+- [#900](https://github.com/sveltejs/eslint-plugin-svelte/pull/900) [`4759b47`](https://github.com/sveltejs/eslint-plugin-svelte/commit/4759b47b195abee605a0597360fc9fc4c6d95f68) Thanks [@marekdedic](https://github.com/marekdedic)! - feat: added the no-navigation-without-base rule
+
+- [#925](https://github.com/sveltejs/eslint-plugin-svelte/pull/925) [`faf90ef`](https://github.com/sveltejs/eslint-plugin-svelte/commit/faf90ef9a6aab3ec647c30df67a54a25d8322324) Thanks [@marekdedic](https://github.com/marekdedic)! - feat: added the `consistent-selector-style` rule
+
+- [#945](https://github.com/sveltejs/eslint-plugin-svelte/pull/945) [`19f682b`](https://github.com/sveltejs/eslint-plugin-svelte/commit/19f682b73ce6bcccae52da0e59d5ab32a9d2c3c2) Thanks [@baseballyama](https://github.com/baseballyama)! - feat: Support `<svelte:boundary>`
+
+- [#844](https://github.com/sveltejs/eslint-plugin-svelte/pull/844) [`2bbd049`](https://github.com/sveltejs/eslint-plugin-svelte/commit/2bbd0497ab7e05db0aab3c8958db08e3fdf4b9b2) Thanks [@Winter](https://github.com/Winter)! - feat: Added suggestion to the `block-lang` rule.
+
+- [#984](https://github.com/sveltejs/eslint-plugin-svelte/pull/984) [`35d80a5`](https://github.com/sveltejs/eslint-plugin-svelte/commit/35d80a50f1053666153bfc7221b945055bfb76d1) Thanks [@baseballyama](https://github.com/baseballyama)! - feat: support `warningFilter` in `valid-compile` rule
+
+- [#933](https://github.com/sveltejs/eslint-plugin-svelte/pull/933) [`71eca84`](https://github.com/sveltejs/eslint-plugin-svelte/commit/71eca843c43250591ec6fa2dd1dc547b1074d6ad) Thanks [@mikededo](https://github.com/mikededo)! - Add `prefer-const` rule
+
+- [#918](https://github.com/sveltejs/eslint-plugin-svelte/pull/918) [`5da98c9`](https://github.com/sveltejs/eslint-plugin-svelte/commit/5da98c94f452c8436f26af4172e095fd91f66e1a) Thanks [@mikededo](https://github.com/mikededo)! - Added new `no-deprecated-raw-special-elements` rule
+
+- [#922](https://github.com/sveltejs/eslint-plugin-svelte/pull/922) [`f4a0fa7`](https://github.com/sveltejs/eslint-plugin-svelte/commit/f4a0fa78e06091348d985b5442a390eae47b0f4f) Thanks [@marekdedic](https://github.com/marekdedic)! - feat: added the no-useless-children-snippet rule
+
+- [#836](https://github.com/sveltejs/eslint-plugin-svelte/pull/836) [`3fa90aa`](https://github.com/sveltejs/eslint-plugin-svelte/commit/3fa90aa57a15ad18105b0d80b1ed975f1f782a11) Thanks [@renovate](https://github.com/apps/renovate)! - feat: support for typescript-eslint v8 to `svelte/indent` rule
+
+- [#963](https://github.com/sveltejs/eslint-plugin-svelte/pull/963) [`2c551b2`](https://github.com/sveltejs/eslint-plugin-svelte/commit/2c551b20557bcd53e35479336bf0c25e88a7643b) Thanks [@baseballyama](https://github.com/baseballyama)! - feat: support Svelte5 of `valid-prop-names-in-kit-pages` rule
+
+- [#1054](https://github.com/sveltejs/eslint-plugin-svelte/pull/1054) [`c587629`](https://github.com/sveltejs/eslint-plugin-svelte/commit/c587629ba2a7d7742965367eb3ad797a9075ef8a) Thanks [@marekdedic](https://github.com/marekdedic)! - feat: added the valid-style-parse rule
+
+- [#1085](https://github.com/sveltejs/eslint-plugin-svelte/pull/1085) [`a0588ef`](https://github.com/sveltejs/eslint-plugin-svelte/commit/a0588ef1fa2d3662a664f4d5564f9f225c67696e) Thanks [@baseballyama](https://github.com/baseballyama)! - chore: update `svelte-eslint-parser` to v1
+
+- [#1015](https://github.com/sveltejs/eslint-plugin-svelte/pull/1015) [`8369eaf`](https://github.com/sveltejs/eslint-plugin-svelte/commit/8369eaf5d2e77fccf0ac9fb3f663d94a2b323a4f) Thanks [@mikededo](https://github.com/mikededo)! - fix!: rename `no-deprecated-raw-special-elements` to `no-raw-special-elements`
+
+- [#911](https://github.com/sveltejs/eslint-plugin-svelte/pull/911) [`452ffed`](https://github.com/sveltejs/eslint-plugin-svelte/commit/452ffed53791cb9e158636bcd80a221d2840cc4a) Thanks [@marekdedic](https://github.com/marekdedic)! - feat(no-inline-styles): allowing transitions by default
+
+- [#1063](https://github.com/sveltejs/eslint-plugin-svelte/pull/1063) [`d39c90c`](https://github.com/sveltejs/eslint-plugin-svelte/commit/d39c90c86edfedb9be42a011a5ca4573f6661397) Thanks [@baseballyama](https://github.com/baseballyama)! - feat: detect version information from node_modules when not specified in package.json, like pnpm’s catalog
+
+### Patch Changes
+
+- [#961](https://github.com/sveltejs/eslint-plugin-svelte/pull/961) [`117e60d`](https://github.com/sveltejs/eslint-plugin-svelte/commit/117e60d4290966911450c7e0db8566279e4511bb) Thanks [@baseballyama](https://github.com/baseballyama)! - fix: support each blocks without an item
+
+- [#1009](https://github.com/sveltejs/eslint-plugin-svelte/pull/1009) [`a003664`](https://github.com/sveltejs/eslint-plugin-svelte/commit/a0036643b5451f0423cd61dafd092c39bd6f4bcb) Thanks [@baseballyama](https://github.com/baseballyama)! - chore: upgrade `svelte-eslint-parser` to `1.0.0-next.8`
+
+- [#1016](https://github.com/sveltejs/eslint-plugin-svelte/pull/1016) [`91999e3`](https://github.com/sveltejs/eslint-plugin-svelte/commit/91999e3520afe42b3cc51f0823f7c912b97176b4) Thanks [@baseballyama](https://github.com/baseballyama)! - chore: change the rule category of `valid-prop-names-in-kit-pages` to `SvelteKit`
+
+- [#993](https://github.com/sveltejs/eslint-plugin-svelte/pull/993) [`b97a13e`](https://github.com/sveltejs/eslint-plugin-svelte/commit/b97a13eb02f9c72346f29e64734f0a304890a197) Thanks [@baseballyama](https://github.com/baseballyama)! - chore: add `:exit` for each node listener
+
+- [#1048](https://github.com/sveltejs/eslint-plugin-svelte/pull/1048) [`513806c`](https://github.com/sveltejs/eslint-plugin-svelte/commit/513806cafe221487afd32bdcaa33ba8852dc881f) Thanks [@baseballyama](https://github.com/baseballyama)! - fix: allow `children` in `valid-prop-names-in-kit-pages` rule
+
+- [#1012](https://github.com/sveltejs/eslint-plugin-svelte/pull/1012) [`763cf7a`](https://github.com/sveltejs/eslint-plugin-svelte/commit/763cf7ace209dfb90cf7d1d7e6699a6c0fe240d6) Thanks [@baseballyama](https://github.com/baseballyama)! - chore: change the rule category of `no-export-load-in-svelte-module-in-kit-pages` to `SvelteKit`
+
+- [#1021](https://github.com/sveltejs/eslint-plugin-svelte/pull/1021) [`6557c69`](https://github.com/sveltejs/eslint-plugin-svelte/commit/6557c69d7f3595cdf226e681cadf3d0df4c5d972) Thanks [@baseballyama](https://github.com/baseballyama)! - chore: update `svelte-eslint-parser` to `1.0.0-next.10`
+
+- [#956](https://github.com/sveltejs/eslint-plugin-svelte/pull/956) [`157ee1f`](https://github.com/sveltejs/eslint-plugin-svelte/commit/157ee1fade79aab88f01d125b0b01cf375da4cd1) Thanks [@baseballyama](https://github.com/baseballyama)! - chore: update `svelte-eslint-parser` to v1.0.0-next.4
+
+- [#965](https://github.com/sveltejs/eslint-plugin-svelte/pull/965) [`47760ad`](https://github.com/sveltejs/eslint-plugin-svelte/commit/47760ad1b7f6b83d4c29380b3ef3cf09cde42dc8) Thanks [@marekdedic](https://github.com/marekdedic)! - chore: using svelte-eslint-parser for style selector parsing
+
+- [#990](https://github.com/sveltejs/eslint-plugin-svelte/pull/990) [`12049c0`](https://github.com/sveltejs/eslint-plugin-svelte/commit/12049c026f529feff6056e679ba62f07de948aa5) Thanks [@baseballyama](https://github.com/baseballyama)! - fix: ignore `css_unused_selector` compile error if `<style>` tag has `global` attribute
+
+- [#1035](https://github.com/sveltejs/eslint-plugin-svelte/pull/1035) [`f16729f`](https://github.com/sveltejs/eslint-plugin-svelte/commit/f16729f55877b1768ec8d240fd8e416f141781ce) Thanks [@baseballyama](https://github.com/baseballyama)! - chore: run `require-event-dispatcher-types` rule on Svelte 3/4 only
+
+- [#1040](https://github.com/sveltejs/eslint-plugin-svelte/pull/1040) [`ac7115c`](https://github.com/sveltejs/eslint-plugin-svelte/commit/ac7115c74b3f1e82ef15be81d9ef2026da76bb11) Thanks [@baseballyama](https://github.com/baseballyama)! - fix: account for \n and \r in `TemplateLiteral` handling for the `no-useless-mustaches` rule
+
+- [#1020](https://github.com/sveltejs/eslint-plugin-svelte/pull/1020) [`eae0e2e`](https://github.com/sveltejs/eslint-plugin-svelte/commit/eae0e2e52c2812ea630eea45e5be4f439191c806) Thanks [@baseballyama](https://github.com/baseballyama)! - chore: update `svelte-eslint-parser` to `1.0.0-next.9`
+
+- [#1017](https://github.com/sveltejs/eslint-plugin-svelte/pull/1017) [`806d72a`](https://github.com/sveltejs/eslint-plugin-svelte/commit/806d72ad55908fb967252ea0514672b026a6bd09) Thanks [@baseballyama](https://github.com/baseballyama)! - chore: do not run `no-reactive-functions` rule on Svelte 5 with runes
+
+- [#1014](https://github.com/sveltejs/eslint-plugin-svelte/pull/1014) [`74373ec`](https://github.com/sveltejs/eslint-plugin-svelte/commit/74373ec77aa9063c64657faefc01ca331e27b599) Thanks [@baseballyama](https://github.com/baseballyama)! - chore: do not run `no-reactive-reassign` rule on Svelte 5 with runes
+
+- [#1026](https://github.com/sveltejs/eslint-plugin-svelte/pull/1026) [`1bed311`](https://github.com/sveltejs/eslint-plugin-svelte/commit/1bed311084c58a9893e2b578f8b34c2fcb2e8d8b) Thanks [@baseballyama](https://github.com/baseballyama)! - chore: update `svelte-eslint-parser` to `v1.0.0-next.12`
+
+- [#941](https://github.com/sveltejs/eslint-plugin-svelte/pull/941) [`fce2f74`](https://github.com/sveltejs/eslint-plugin-svelte/commit/fce2f74b4b2fe8185742f0411739103301f8ea9f) Thanks [@ota-meshi](https://github.com/ota-meshi)! - fix: crash with eslint v9.16.0 in `svelte/no-inner-declarations`
+
+- [#1018](https://github.com/sveltejs/eslint-plugin-svelte/pull/1018) [`5bdc906`](https://github.com/sveltejs/eslint-plugin-svelte/commit/5bdc906fc1e32835ab3b75dfd2a6a08b4cbb968b) Thanks [@baseballyama](https://github.com/baseballyama)! - chore: run the `no-inspect` rule only in Svelte 5’s runes mode
+
+- [#1006](https://github.com/sveltejs/eslint-plugin-svelte/pull/1006) [`5fd91ba`](https://github.com/sveltejs/eslint-plugin-svelte/commit/5fd91baa1835cbffc58a8c473ccf70f3f02a34e6) Thanks [@baseballyama](https://github.com/baseballyama)! - chore: do not run `infinite-reactive-loop` rule on Svelte 5 with runes
+
+- [#1031](https://github.com/sveltejs/eslint-plugin-svelte/pull/1031) [`e50d2d4`](https://github.com/sveltejs/eslint-plugin-svelte/commit/e50d2d4a8820c222696c049e0b01988626845584) Thanks [@baseballyama](https://github.com/baseballyama)! - chore: do not run `no-reactive-literals` rule on Svelte 5 with runes
+
+- [#1032](https://github.com/sveltejs/eslint-plugin-svelte/pull/1032) [`722b36c`](https://github.com/sveltejs/eslint-plugin-svelte/commit/722b36ce3b8a16b965f61701dead22b95c7e8b3d) Thanks [@baseballyama](https://github.com/baseballyama)! - chore: run `no-useless-children-snippet` rule on Svelte 5 only
+
+- [#1007](https://github.com/sveltejs/eslint-plugin-svelte/pull/1007) [`8e9199a`](https://github.com/sveltejs/eslint-plugin-svelte/commit/8e9199ae326110778e4b0557616d394c6ac5e847) Thanks [@baseballyama](https://github.com/baseballyama)! - fix: update method for extracting major version
+
 ## 3.0.0-next.18
 
 ### Patch Changes
diff --git a/packages/eslint-plugin-svelte/package.json b/packages/eslint-plugin-svelte/package.json
index c92be3b..b56698a 100644
--- a/packages/eslint-plugin-svelte/package.json
+++ b/packages/eslint-plugin-svelte/package.json
@@ -1,6 +1,6 @@
 {
   "name": "eslint-plugin-svelte",
-  "version": "3.0.0-next.18",
+  "version": "3.0.3",
   "description": "ESLint plugin for Svelte using AST",
   "repository": "git+https://github.com/sveltejs/eslint-plugin-svelte.git",
   "homepage": "https://sveltejs.github.io/eslint-plugin-svelte",
@@ -8,7 +8,7 @@
   "funding": "https://github.com/sponsors/ota-meshi",
   "license": "MIT",
   "engines": {
-    "node": "^18.20.4 || ^20.18.0 || >=22.10.0"
+    "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
   },
   "type": "module",
   "main": "lib/index.js",
@@ -65,7 +65,7 @@
     "postcss-load-config": "^3.1.4",
     "postcss-safe-parser": "^7.0.0",
     "semver": "^7.6.3",
-    "svelte-eslint-parser": "^1.0.0-next.13"
+    "svelte-eslint-parser": "^1.0.1"
   },
   "devDependencies": {
     "@babel/core": "^7.26.0",
@@ -86,7 +86,7 @@
     "assert": "^2.1.0",
     "esbuild": "^0.25.0",
     "eslint-scope": "^8.2.0",
-    "eslint-typegen": "^1.0.0",
+    "eslint-typegen": "^2.0.0",
     "eslint-visitor-keys": "^4.2.0",
     "espree": "^10.3.0",
     "less": "^4.2.1",
diff --git a/packages/eslint-plugin-svelte/src/configs/flat/recommended.ts b/packages/eslint-plugin-svelte/src/configs/flat/recommended.ts
index fc7f089..9a9792e 100644
--- a/packages/eslint-plugin-svelte/src/configs/flat/recommended.ts
+++ b/packages/eslint-plugin-svelte/src/configs/flat/recommended.ts
@@ -38,7 +38,6 @@ const config: Linter.Config[] = [
 			'svelte/require-each-key': 'error',
 			'svelte/require-event-dispatcher-types': 'error',
 			'svelte/require-store-reactive-access': 'error',
-			'svelte/require-stores-init': 'error',
 			'svelte/system': 'error',
 			'svelte/valid-each-key': 'error',
 			'svelte/valid-prop-names-in-kit-pages': 'error'
diff --git a/packages/eslint-plugin-svelte/src/meta.ts b/packages/eslint-plugin-svelte/src/meta.ts
index 8b63b17..c00ff5b 100644
--- a/packages/eslint-plugin-svelte/src/meta.ts
+++ b/packages/eslint-plugin-svelte/src/meta.ts
@@ -2,4 +2,4 @@
 // This file has been automatically generated,
 // in order to update its content execute "pnpm run update"
 export const name = 'eslint-plugin-svelte';
-export const version = '3.0.0-next.18';
+export const version = '3.0.3';
diff --git a/packages/eslint-plugin-svelte/src/rule-types.ts b/packages/eslint-plugin-svelte/src/rule-types.ts
index 30f15c1..88c07ac 100644
--- a/packages/eslint-plugin-svelte/src/rule-types.ts
+++ b/packages/eslint-plugin-svelte/src/rule-types.ts
@@ -366,6 +366,11 @@ export interface RuleOptions {
    * @see https://sveltejs.github.io/eslint-plugin-svelte/rules/valid-prop-names-in-kit-pages/
    */
   'svelte/valid-prop-names-in-kit-pages'?: Linter.RuleEntry<[]>
+  /**
+   * require valid style element parsing
+   * @see https://sveltejs.github.io/eslint-plugin-svelte/rules/valid-style-parse/
+   */
+  'svelte/valid-style-parse'?: Linter.RuleEntry<[]>
 }
 
 /* ======= Declarations ======= */
@@ -525,6 +530,7 @@ type SveltePreferClassDirective = []|[{
 type SveltePreferConst = []|[{
   destructuring?: ("any" | "all")
   ignoreReadBeforeAssign?: boolean
+  excludedRunes?: string[]
 }]
 // ----- svelte/shorthand-attribute -----
 type SvelteShorthandAttribute = []|[{
diff --git a/packages/eslint-plugin-svelte/src/rules/no-useless-mustaches.ts b/packages/eslint-plugin-svelte/src/rules/no-useless-mustaches.ts
index 169cc8e..05d3af2 100644
--- a/packages/eslint-plugin-svelte/src/rules/no-useless-mustaches.ts
+++ b/packages/eslint-plugin-svelte/src/rules/no-useless-mustaches.ts
@@ -85,6 +85,10 @@ export default createRule('no-useless-mustaches', {
 				return;
 			}
 
+			if (rawValue.includes('{')) {
+				return;
+			}
+
 			let hasEscape = false;
 			if (rawValue !== strValue) {
 				// check escapes
diff --git a/packages/eslint-plugin-svelte/src/rules/prefer-const.ts b/packages/eslint-plugin-svelte/src/rules/prefer-const.ts
index 0d079b1..842bbc9 100644
--- a/packages/eslint-plugin-svelte/src/rules/prefer-const.ts
+++ b/packages/eslint-plugin-svelte/src/rules/prefer-const.ts
@@ -21,7 +21,7 @@ function findDeclarationCallee(node: TSESTree.Expression) {
  * Determines if a declaration should be skipped in the const preference analysis.
  * Specifically checks for Svelte's state management utilities ($props, $derived).
  */
-function shouldSkipDeclaration(declaration: TSESTree.Expression | null) {
+function shouldSkipDeclaration(declaration: TSESTree.Expression | null, excludedRunes: string[]) {
 	if (!declaration) {
 		return false;
 	}
@@ -31,7 +31,7 @@ function shouldSkipDeclaration(declaration: TSESTree.Expression | null) {
 		return false;
 	}
 
-	if (callee.type === 'Identifier' && ['$props', '$derived'].includes(callee.name)) {
+	if (callee.type === 'Identifier' && excludedRunes.includes(callee.name)) {
 		return true;
 	}
 
@@ -39,11 +39,7 @@ function shouldSkipDeclaration(declaration: TSESTree.Expression | null) {
 		return false;
 	}
 
-	if (
-		callee.object.name === '$derived' &&
-		callee.property.type === 'Identifier' &&
-		callee.property.name === 'by'
-	) {
+	if (excludedRunes.includes(callee.object.name)) {
 		return true;
 	}
 
@@ -58,16 +54,35 @@ export default createRule('prefer-const', {
 			category: 'Best Practices',
 			recommended: false,
 			extensionRule: 'prefer-const'
-		}
+		},
+		schema: [
+			{
+				type: 'object',
+				properties: {
+					destructuring: { enum: ['any', 'all'] },
+					ignoreReadBeforeAssign: { type: 'boolean' },
+					excludedRunes: {
+						type: 'array',
+						items: {
+							type: 'string'
+						}
+					}
+				},
+				additionalProperties: false
+			}
+		]
 	},
 	create(context) {
+		const config = context.options[0] ?? {};
+		const excludedRunes = config.excludedRunes ?? ['$props', '$derived'];
+
 		return defineWrapperListener(coreRule, context, {
 			createListenerProxy(coreListener) {
 				return {
 					...coreListener,
 					VariableDeclaration(node) {
 						for (const decl of node.declarations) {
-							if (shouldSkipDeclaration(decl.init)) {
+							if (shouldSkipDeclaration(decl.init, excludedRunes)) {
 								return;
 							}
 						}
diff --git a/packages/eslint-plugin-svelte/src/rules/require-stores-init.ts b/packages/eslint-plugin-svelte/src/rules/require-stores-init.ts
index 820267e..7683c1e 100644
--- a/packages/eslint-plugin-svelte/src/rules/require-stores-init.ts
+++ b/packages/eslint-plugin-svelte/src/rules/require-stores-init.ts
@@ -6,7 +6,9 @@ export default createRule('require-stores-init', {
 		docs: {
 			description: 'require initial value in store',
 			category: 'Best Practices',
-			recommended: true
+			// Please refer to the following before setting recommended to true.
+			// https://github.com/sveltejs/eslint-plugin-svelte/issues/1073
+			recommended: false
 		},
 		schema: [],
 		messages: {
diff --git a/packages/eslint-plugin-svelte/src/rules/valid-prop-names-in-kit-pages.ts b/packages/eslint-plugin-svelte/src/rules/valid-prop-names-in-kit-pages.ts
index ab3f9d5..f6b21dd 100644
--- a/packages/eslint-plugin-svelte/src/rules/valid-prop-names-in-kit-pages.ts
+++ b/packages/eslint-plugin-svelte/src/rules/valid-prop-names-in-kit-pages.ts
@@ -3,7 +3,6 @@ import type { TSESTree } from '@typescript-eslint/types';
 import { createRule } from '../utils/index.js';
 import type { RuleContext } from '../types.js';
 import { getSvelteVersion } from '../utils/svelte-context.js';
-import { getFilename } from '../utils/compat.js';
 
 const EXPECTED_PROP_NAMES = ['data', 'errors', 'form', 'snapshot'];
 const EXPECTED_PROP_NAMES_SVELTE5 = [...EXPECTED_PROP_NAMES, 'children'];
@@ -29,6 +28,23 @@ function checkProp(
 	}
 }
 
+function isModuleScript(node: AST.SvelteAttribute) {
+	// <script context="module">
+	if (
+		node.key.name === 'context' &&
+		node.value.some((v) => v.type === 'SvelteLiteral' && v.value === 'module')
+	) {
+		return true;
+	}
+
+	// <script module>
+	if (node.key.name === 'module' && node.value.length === 0) {
+		return true;
+	}
+
+	return false;
+}
+
 export default createRule('valid-prop-names-in-kit-pages', {
 	meta: {
 		docs: {
@@ -49,18 +65,13 @@ export default createRule('valid-prop-names-in-kit-pages', {
 	},
 	create(context) {
 		let isScript = false;
-		const isSvelte5 = getSvelteVersion(getFilename(context)) === '5';
+		const isSvelte5 = getSvelteVersion() === '5';
 		const expectedPropNames = isSvelte5 ? EXPECTED_PROP_NAMES_SVELTE5 : EXPECTED_PROP_NAMES;
 		return {
 			// <script>
 			'Program > SvelteScriptElement > SvelteStartTag': (node: AST.SvelteStartTag) => {
 				// except for <script context="module">
-				isScript = !node.attributes.some(
-					(a) =>
-						a.type === 'SvelteAttribute' &&
-						a.key.name === 'context' &&
-						a.value.some((v) => v.type === 'SvelteLiteral' && v.value === 'module')
-				);
+				isScript = !node.attributes.some((a) => a.type === 'SvelteAttribute' && isModuleScript(a));
 			},
 
 			// </script>
diff --git a/packages/eslint-plugin-svelte/src/rules/valid-style-parse.ts b/packages/eslint-plugin-svelte/src/rules/valid-style-parse.ts
new file mode 100644
index 0000000..685c68a
--- /dev/null
+++ b/packages/eslint-plugin-svelte/src/rules/valid-style-parse.ts
@@ -0,0 +1,40 @@
+import { createRule } from '../utils/index.js';
+import { getCwd, getSourceCode } from '../utils/compat.js';
+
+export default createRule('valid-style-parse', {
+	meta: {
+		docs: {
+			description: 'require valid style element parsing',
+			category: 'Possible Errors',
+			recommended: false
+		},
+		schema: [],
+		messages: {},
+		type: 'problem'
+	},
+	create(context) {
+		const sourceCode = getSourceCode(context);
+		if (!sourceCode.parserServices.isSvelte) {
+			return {};
+		}
+		const cwd = `${getCwd(context)}/`;
+
+		return {
+			SvelteStyleElement(node) {
+				const styleContext = sourceCode.parserServices.getStyleContext!();
+				if (styleContext.status === 'parse-error') {
+					context.report({
+						loc: node.loc,
+						message: `Error parsing style element. Error message: "${styleContext.error.message.replace(cwd, '')}"`
+					});
+				}
+				if (styleContext.status === 'unknown-lang') {
+					context.report({
+						loc: node.loc,
+						message: `Found unsupported style element language "${styleContext.sourceLang}"`
+					});
+				}
+			}
+		};
+	}
+});
diff --git a/packages/eslint-plugin-svelte/src/utils/get-node-module.ts b/packages/eslint-plugin-svelte/src/utils/get-node-module.ts
new file mode 100644
index 0000000..9b2a445
--- /dev/null
+++ b/packages/eslint-plugin-svelte/src/utils/get-node-module.ts
@@ -0,0 +1,71 @@
+import fs from 'fs';
+import path from 'path';
+import { createCache } from './cache.js';
+
+const isRunOnBrowser = !fs.readFileSync;
+const nodeModuleCache = createCache<string | null>();
+const nodeModulesCache = createCache<string[]>();
+
+/**
+ * Find package directory in node_modules
+ */
+function findPackageInNodeModules(dir: string, packageName: string): string | null {
+	if (isRunOnBrowser) return null;
+
+	const nodeModulesPath = path.join(dir, 'node_modules');
+	const packagePath = path.join(nodeModulesPath, packageName);
+
+	try {
+		const stats = fs.statSync(packagePath);
+		if (stats.isDirectory()) {
+			return packagePath;
+		}
+	} catch {
+		// ignore if directory not found
+	}
+
+	return null;
+}
+
+/**
+ * Get first found package path from node_modules
+ */
+export function getNodeModule(packageName: string, startPath = 'a.js'): string | null {
+	if (isRunOnBrowser) return null;
+
+	const cacheKey = `${startPath}:${packageName}`;
+	const cached = nodeModulesCache.get(cacheKey);
+	if (cached) {
+		return cached[0] ?? null;
+	}
+
+	const startDir = path.dirname(path.resolve(startPath));
+	let dir = startDir;
+	let prevDir = '';
+
+	do {
+		// check cache
+		const cachePath = nodeModuleCache.get(`${dir}:${packageName}`);
+		if (cachePath) {
+			if (cachePath !== null) {
+				nodeModulesCache.set(cacheKey, [cachePath]);
+				return cachePath;
+			}
+		} else {
+			// search new
+			const packagePath = findPackageInNodeModules(dir, packageName);
+			nodeModuleCache.set(`${dir}:${packageName}`, packagePath);
+			if (packagePath) {
+				nodeModulesCache.set(cacheKey, [packagePath]);
+				return packagePath;
+			}
+		}
+
+		// go to parent
+		prevDir = dir;
+		dir = path.resolve(dir, '..');
+	} while (dir !== prevDir);
+
+	nodeModulesCache.set(cacheKey, []);
+	return null;
+}
diff --git a/packages/eslint-plugin-svelte/src/utils/rules.ts b/packages/eslint-plugin-svelte/src/utils/rules.ts
index 2a2ddee..13d3bd6 100644
--- a/packages/eslint-plugin-svelte/src/utils/rules.ts
+++ b/packages/eslint-plugin-svelte/src/utils/rules.ts
@@ -72,6 +72,7 @@ import system from '../rules/system.js';
 import validCompile from '../rules/valid-compile.js';
 import validEachKey from '../rules/valid-each-key.js';
 import validPropNamesInKitPages from '../rules/valid-prop-names-in-kit-pages.js';
+import validStyleParse from '../rules/valid-style-parse.js';
 
 export const rules = [
 	typescriptEslintNoUnnecessaryCondition,
@@ -143,5 +144,6 @@ export const rules = [
 	system,
 	validCompile,
 	validEachKey,
-	validPropNamesInKitPages
+	validPropNamesInKitPages,
+	validStyleParse
 ] as RuleModule[];
diff --git a/packages/eslint-plugin-svelte/src/utils/svelte-context.ts b/packages/eslint-plugin-svelte/src/utils/svelte-context.ts
index e821e3a..e4cb124 100644
--- a/packages/eslint-plugin-svelte/src/utils/svelte-context.ts
+++ b/packages/eslint-plugin-svelte/src/utils/svelte-context.ts
@@ -2,8 +2,10 @@ import type { RuleContext } from '../types.js';
 import fs from 'fs';
 import path from 'path';
 import { getPackageJsons } from './get-package-json.js';
+import { getNodeModule } from './get-node-module.js';
 import { getFilename, getSourceCode } from './compat.js';
 import { createCache } from './cache.js';
+import { VERSION as SVELTE_VERSION } from 'svelte/compiler';
 
 const isRunInBrowser = !fs.readFileSync;
 
@@ -168,51 +170,37 @@ function getSvelteKitContext(
 	return result;
 }
 
-const svelteVersionCache = createCache<SvelteContext['svelteVersion']>();
-
-export function getSvelteVersion(filePath: string): SvelteContext['svelteVersion'] {
-	const cached = svelteVersionCache.get(filePath);
-	if (cached) return cached;
+function checkAndSetSvelteVersion(version: string): SvelteContext['svelteVersion'] | null {
+	const major = extractMajorVersion(version, false);
+	if (major == null) {
+		return null;
+	}
+	if (major === '3' || major === '4') {
+		return '3/4';
+	}
+	return major as SvelteContext['svelteVersion'];
+}
 
+export function getSvelteVersion(): SvelteContext['svelteVersion'] {
 	// Hack: if it runs in browser, it regards as Svelte project.
 	if (isRunInBrowser) {
-		svelteVersionCache.set(filePath, '5');
 		return '5';
 	}
 
-	try {
-		const packageJsons = getPackageJsons(filePath);
-		for (const packageJson of packageJsons) {
-			const version = packageJson.dependencies?.svelte ?? packageJson.devDependencies?.svelte;
-			if (typeof version !== 'string') {
-				continue;
-			}
-			const major = extractMajorVersion(version, false);
-			if (major === '3' || major === '4') {
-				svelteVersionCache.set(filePath, '3/4');
-				return '3/4';
-			}
-			svelteVersionCache.set(filePath, major as SvelteContext['svelteVersion']);
-			return major as SvelteContext['svelteVersion'];
-		}
-	} catch {
-		/** do nothing */
-	}
-
-	svelteVersionCache.set(filePath, null);
-	return null;
+	return checkAndSetSvelteVersion(SVELTE_VERSION);
 }
 
 const svelteKitVersionCache = createCache<SvelteContext['svelteKitVersion']>();
 
-/**
- * Check givin file is under SvelteKit project.
- *
- * If it runs on browser, it always returns true.
- *
- * @param filePath A file path.
- * @returns
- */
+function checkAndSetSvelteKitVersion(
+	version: string,
+	filePath: string
+): SvelteContext['svelteKitVersion'] {
+	const major = extractMajorVersion(version, true) as SvelteContext['svelteKitVersion'];
+	svelteKitVersionCache.set(filePath, major);
+	return major;
+}
+
 function getSvelteKitVersion(filePath: string): SvelteContext['svelteKitVersion'] {
 	const cached = svelteKitVersionCache.get(filePath);
 	if (cached) return cached;
@@ -223,27 +211,42 @@ function getSvelteKitVersion(filePath: string): SvelteContext['svelteKitVersion'
 		return '2';
 	}
 
+	const nodeModule = getNodeModule('@sveltejs/kit', filePath);
+	if (nodeModule) {
+		try {
+			const packageJson = JSON.parse(
+				fs.readFileSync(path.join(nodeModule, 'package.json'), 'utf8')
+			);
+			const result = checkAndSetSvelteKitVersion(packageJson.version, filePath);
+			if (result != null) {
+				return result;
+			}
+		} catch {
+			/** do nothing */
+		}
+	}
+
 	try {
 		const packageJsons = getPackageJsons(filePath);
-		if (packageJsons.length === 0) return null;
-		if (packageJsons[0].name === 'eslint-plugin-svelte') {
-			// Hack: CI removes `@sveltejs/kit` and it returns false and test failed.
-			// So always it returns 2 if it runs on the package.
-			svelteKitVersionCache.set(filePath, '2');
-			return '2';
-		}
+		if (packageJsons.length > 0) {
+			if (packageJsons[0].name === 'eslint-plugin-svelte') {
+				// Hack: CI removes `@sveltejs/kit` and it returns false and test failed.
+				// So always it returns 2 if it runs on the package.
+				svelteKitVersionCache.set(filePath, '2');
+				return '2';
+			}
 
-		for (const packageJson of packageJsons) {
-			const version =
-				packageJson.dependencies?.['@sveltejs/kit'] ??
-				packageJson.devDependencies?.['@sveltejs/kit'];
-			if (typeof version !== 'string') {
-				svelteKitVersionCache.set(filePath, null);
-				return null;
+			for (const packageJson of packageJsons) {
+				const version =
+					packageJson.dependencies?.['@sveltejs/kit'] ??
+					packageJson.devDependencies?.['@sveltejs/kit'];
+				if (typeof version === 'string') {
+					const result = checkAndSetSvelteKitVersion(version, filePath);
+					if (result != null) {
+						return result;
+					}
+				}
 			}
-			const major = extractMajorVersion(version, true) as SvelteContext['svelteKitVersion'];
-			svelteKitVersionCache.set(filePath, major);
-			return major;
 		}
 	} catch {
 		/** do nothing */
@@ -291,7 +294,7 @@ export function getSvelteContext(context: RuleContext): SvelteContext | null {
 	if (cached) return cached;
 
 	const svelteKitContext = getSvelteKitContext(context);
-	const svelteVersion = getSvelteVersion(filePath);
+	const svelteVersion = getSvelteVersion();
 	const svelteFileType = getSvelteFileType(filePath);
 
 	if (svelteVersion == null) {


Test patch:
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-useless-mustaches/valid/valid-test01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-useless-mustaches/valid/valid-test01-input.svelte
index 5da305a..46402ae 100644
--- a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-useless-mustaches/valid/valid-test01-input.svelte
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-useless-mustaches/valid/valid-test01-input.svelte
@@ -8,5 +8,6 @@ foo 'foo'
 {1}
 {null}
 {`foo${foo}`}
+{'{foo'}
 
 <div data-text="foo 'foo' {foo} {'foo' || 'bar'} {1} {null}" />
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/invalid/option1/_config.json b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/invalid/option1/_config.json
new file mode 100644
index 0000000..0751a96
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/invalid/option1/_config.json
@@ -0,0 +1,3 @@
+{
+	"options": [{ "excludedRunes": [] }]
+}
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/invalid/option1/test01-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/invalid/option1/test01-errors.yaml
new file mode 100644
index 0000000..03d2d8e
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/invalid/option1/test01-errors.yaml
@@ -0,0 +1,20 @@
+- message: "'prop1' is never reassigned. Use 'const' instead."
+  line: 2
+  column: 8
+  suggestions: null
+- message: "'prop2' is never reassigned. Use 'const' instead."
+  line: 2
+  column: 15
+  suggestions: null
+- message: "'zero' is never reassigned. Use 'const' instead."
+  line: 3
+  column: 6
+  suggestions: null
+- message: "'derived' is never reassigned. Use 'const' instead."
+  line: 4
+  column: 6
+  suggestions: null
+- message: "'derivedBy' is never reassigned. Use 'const' instead."
+  line: 5
+  column: 6
+  suggestions: null
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/invalid/option1/test01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/invalid/option1/test01-input.svelte
new file mode 100644
index 0000000..97f28d4
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/invalid/option1/test01-input.svelte
@@ -0,0 +1,6 @@
+<script>
+	let { prop1, prop2 } = $props();
+	let zero = $state(0);
+	let derived = $derived(zero * 2);
+	let derivedBy = $derived.by(calc());
+</script>
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/invalid/option1/test01-output.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/invalid/option1/test01-output.svelte
new file mode 100644
index 0000000..dd1b99c
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/invalid/option1/test01-output.svelte
@@ -0,0 +1,6 @@
+<script>
+	const { prop1, prop2 } = $props();
+	const zero = $state(0);
+	const derived = $derived(zero * 2);
+	const derivedBy = $derived.by(calc());
+</script>
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/invalid/option2/_config.json b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/invalid/option2/_config.json
new file mode 100644
index 0000000..9021ae6
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/invalid/option2/_config.json
@@ -0,0 +1,3 @@
+{
+	"options": [{ "excludedRunes": ["$state"] }]
+}
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/invalid/option2/test01-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/invalid/option2/test01-errors.yaml
new file mode 100644
index 0000000..b784981
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/invalid/option2/test01-errors.yaml
@@ -0,0 +1,16 @@
+- message: "'prop1' is never reassigned. Use 'const' instead."
+  line: 2
+  column: 8
+  suggestions: null
+- message: "'prop2' is never reassigned. Use 'const' instead."
+  line: 2
+  column: 15
+  suggestions: null
+- message: "'derived' is never reassigned. Use 'const' instead."
+  line: 4
+  column: 6
+  suggestions: null
+- message: "'derivedBy' is never reassigned. Use 'const' instead."
+  line: 5
+  column: 6
+  suggestions: null
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/invalid/option2/test01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/invalid/option2/test01-input.svelte
new file mode 100644
index 0000000..97f28d4
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/invalid/option2/test01-input.svelte
@@ -0,0 +1,6 @@
+<script>
+	let { prop1, prop2 } = $props();
+	let zero = $state(0);
+	let derived = $derived(zero * 2);
+	let derivedBy = $derived.by(calc());
+</script>
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/invalid/option2/test01-output.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/invalid/option2/test01-output.svelte
new file mode 100644
index 0000000..2e25c28
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/invalid/option2/test01-output.svelte
@@ -0,0 +1,6 @@
+<script>
+	const { prop1, prop2 } = $props();
+	let zero = $state(0);
+	const derived = $derived(zero * 2);
+	const derivedBy = $derived.by(calc());
+</script>
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/valid/option1/_config.json b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/valid/option1/_config.json
new file mode 100644
index 0000000..0751a96
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/valid/option1/_config.json
@@ -0,0 +1,3 @@
+{
+	"options": [{ "excludedRunes": [] }]
+}
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/valid/option1/test01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/valid/option1/test01-input.svelte
new file mode 100644
index 0000000..dd1b99c
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/valid/option1/test01-input.svelte
@@ -0,0 +1,6 @@
+<script>
+	const { prop1, prop2 } = $props();
+	const zero = $state(0);
+	const derived = $derived(zero * 2);
+	const derivedBy = $derived.by(calc());
+</script>
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/valid/option2/_config.json b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/valid/option2/_config.json
new file mode 100644
index 0000000..03a86e4
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/valid/option2/_config.json
@@ -0,0 +1,3 @@
+{
+	"options": [{ "excludedRunes": ["$props", "$derived", "$state"] }]
+}
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/valid/option2/test01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/valid/option2/test01-input.svelte
new file mode 100644
index 0000000..97f28d4
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/valid/option2/test01-input.svelte
@@ -0,0 +1,6 @@
+<script>
+	let { prop1, prop2 } = $props();
+	let zero = $state(0);
+	let derived = $derived(zero * 2);
+	let derivedBy = $derived.by(calc());
+</script>
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/valid/test01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/valid/test01-input.svelte
index 5c768eb..33ac253 100644
--- a/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/valid/test01-input.svelte
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/valid/test01-input.svelte
@@ -1,3 +1,6 @@
 <script>
-	const a = {};
+	let { prop1, prop2 } = $props();
+	const zero = $state(0);
+	let derived = $derived(zero * 2);
+	let derivedBy = $derived.by(calc());
 </script>
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test002/+page.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test002-1/+page.svelte
similarity index 100%
rename from packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test002/+page.svelte
rename to packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test002-1/+page.svelte
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test002/_config.json b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test002-1/_config.json
similarity index 100%
rename from packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test002/_config.json
rename to packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test002-1/_config.json
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test002-2/+page.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test002-2/+page.svelte
new file mode 100644
index 0000000..eb7393f
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test002-2/+page.svelte
@@ -0,0 +1,8 @@
+<script module>
+	export let data;
+	export let errors;
+	export let foo;
+	export let bar;
+</script>
+
+{data}, {errors}, {foo}, {bar}
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test003/_config.json b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test002-2/_config.json
similarity index 100%
rename from packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test003/_config.json
rename to packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test002-2/_config.json
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test003/+page.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test003-1/+page.svelte
similarity index 100%
rename from packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test003/+page.svelte
rename to packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test003-1/+page.svelte
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test004/_config.json b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test003-1/_config.json
similarity index 100%
rename from packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test004/_config.json
rename to packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test003-1/_config.json
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test003-2/+page.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test003-2/+page.svelte
new file mode 100644
index 0000000..7eaf286
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test003-2/+page.svelte
@@ -0,0 +1,5 @@
+<script module>
+	export const { data, errors } = { data: {}, errors: {} };
+</script>
+
+{data}, {errors}
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test003-2/_config.json b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test003-2/_config.json
new file mode 100644
index 0000000..9861188
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test003-2/_config.json
@@ -0,0 +1,11 @@
+{
+	"settings": {
+		"svelte": {
+			"kit": {
+				"files": {
+					"routes": "tests/fixtures"
+				}
+			}
+		}
+	}
+}
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test004/+page.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test004-1/+page.svelte
similarity index 100%
rename from packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test004/+page.svelte
rename to packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test004-1/+page.svelte
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test004-1/_config.json b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test004-1/_config.json
new file mode 100644
index 0000000..9861188
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test004-1/_config.json
@@ -0,0 +1,11 @@
+{
+	"settings": {
+		"svelte": {
+			"kit": {
+				"files": {
+					"routes": "tests/fixtures"
+				}
+			}
+		}
+	}
+}
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test004-2/+page.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test004-2/+page.svelte
new file mode 100644
index 0000000..c28b010
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test004-2/+page.svelte
@@ -0,0 +1,5 @@
+<script module>
+	export const { data2: data, errors2: errors } = { data2: {}, errors2: {} };
+</script>
+
+{data}, {errors}
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test004-2/_config.json b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test004-2/_config.json
new file mode 100644
index 0000000..9861188
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/test004-2/_config.json
@@ -0,0 +1,11 @@
+{
+	"settings": {
+		"svelte": {
+			"kit": {
+				"files": {
+					"routes": "tests/fixtures"
+				}
+			}
+		}
+	}
+}
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-style-parse/invalid/invalid-css01-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-style-parse/invalid/invalid-css01-errors.yaml
new file mode 100644
index 0000000..fade069
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-style-parse/invalid/invalid-css01-errors.yaml
@@ -0,0 +1,6 @@
+- message: 'Error parsing style element. Error message:
+    "tests/fixtures/rules/valid-style-parse/invalid/invalid-css01-input.svelte:4:11:
+    Unknown word .div-class/35"'
+  line: 7
+  column: 1
+  suggestions: null
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-style-parse/invalid/invalid-css01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-style-parse/invalid/invalid-css01-input.svelte
new file mode 100644
index 0000000..a3184db
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-style-parse/invalid/invalid-css01-input.svelte
@@ -0,0 +1,18 @@
+<div class="container">
+  <div class="div-class">Hello</div>
+
+  <span class="span-class">World!</span>
+</div>
+
+<style>
+  // This syntax is intentionally invalid CSS - this is to be used to test resiliency against invalid input
+  .container {
+    class .div-class/35
+      # Weird comment
+      color: red;
+
+    .span-class begin
+      font-weight: bold;
+    end
+  }
+</style>
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-style-parse/invalid/invalid-scss01-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-style-parse/invalid/invalid-scss01-errors.yaml
new file mode 100644
index 0000000..5067576
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-style-parse/invalid/invalid-scss01-errors.yaml
@@ -0,0 +1,6 @@
+- message: 'Error parsing style element. Error message:
+    "tests/fixtures/rules/valid-style-parse/invalid/invalid-scss01-input.svelte:4:11:
+    Unknown word .div-class/35"'
+  line: 7
+  column: 1
+  suggestions: null
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-style-parse/invalid/invalid-scss01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-style-parse/invalid/invalid-scss01-input.svelte
new file mode 100644
index 0000000..df4d586
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-style-parse/invalid/invalid-scss01-input.svelte
@@ -0,0 +1,18 @@
+<div class="container">
+  <div class="div-class">Hello</div>
+
+  <span class="span-class">World!</span>
+</div>
+
+<style lang="scss">
+  // This syntax is intentionally invalid CSS - this is to be used to test resiliency against invalid input
+  .container {
+    class .div-class/35
+      # Weird comment
+      color: red;
+
+    .span-class begin
+      font-weight: bold;
+    end
+  }
+</style>
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-style-parse/invalid/unknown-lang01-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-style-parse/invalid/unknown-lang01-errors.yaml
new file mode 100644
index 0000000..0ca96bb
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-style-parse/invalid/unknown-lang01-errors.yaml
@@ -0,0 +1,4 @@
+- message: Found unsupported style element language "invalid-lang"
+  line: 7
+  column: 1
+  suggestions: null
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-style-parse/invalid/unknown-lang01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-style-parse/invalid/unknown-lang01-input.svelte
new file mode 100644
index 0000000..43e1850
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-style-parse/invalid/unknown-lang01-input.svelte
@@ -0,0 +1,18 @@
+<div class="container">
+  <div class="div-class">Hello</div>
+
+  <span class="span-class">World!</span>
+</div>
+
+<style lang="invalid-lang">
+  // This syntax is intentionally invalid CSS - this is to be used to test resiliency against unknown style languages.
+  .container {
+    class .div-class/35
+      # Weird comment
+      color: red;
+
+    .span-class begin
+      font-weight: bold;
+    end
+  }
+</style>
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-style-parse/valid/no-style01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-style-parse/valid/no-style01-input.svelte
new file mode 100644
index 0000000..f3f9e58
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-style-parse/valid/no-style01-input.svelte
@@ -0,0 +1,3 @@
+<a href="https://svelte.dev">Hello</a>
+
+<span style="font-weight: bold;">World!</span>
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-style-parse/valid/valid-css01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-style-parse/valid/valid-css01-input.svelte
new file mode 100644
index 0000000..cca266a
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-style-parse/valid/valid-css01-input.svelte
@@ -0,0 +1,13 @@
+<div class="div-class">Hello</div>
+
+<span class="span-class">World!</span>
+
+<style>
+	.div-class {
+		color: red;
+	}
+
+	.span-class {
+		font-weight: bold;
+	}
+</style>
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-style-parse/valid/valid-scss01-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-style-parse/valid/valid-scss01-input.svelte
new file mode 100644
index 0000000..f7130b5
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-style-parse/valid/valid-scss01-input.svelte
@@ -0,0 +1,18 @@
+<div class="container">
+	<div class="div-class">Hello</div>
+
+	<span class="span-class">World!</span>
+</div>
+
+<style lang="scss">
+	.container {
+		.div-class {
+			// This is an inline comment
+			color: red;
+		}
+
+		.span-class {
+			font-weight: bold;
+		}
+	}
+</style>
diff --git a/packages/eslint-plugin-svelte/tests/src/rules/valid-style-parse.ts b/packages/eslint-plugin-svelte/tests/src/rules/valid-style-parse.ts
new file mode 100644
index 0000000..d5d1c5f
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/src/rules/valid-style-parse.ts
@@ -0,0 +1,12 @@
+import { RuleTester } from '../../utils/eslint-compat.js';
+import rule from '../../../src/rules/valid-style-parse.js';
+import { loadTestCases } from '../../utils/utils.js';
+
+const tester = new RuleTester({
+	languageOptions: {
+		ecmaVersion: 2020,
+		sourceType: 'module'
+	}
+});
+
+tester.run('valid-style-parse', rule as any, loadTestCases('valid-style-parse'));