Repository: sveltejs/eslint-plugin-svelte
Pull request #1041 (2025-01-26 03:27:51)

chore: update README for v3
# ⚠️ We need to merge this PR when we release v3.0.0

I’ve created the README from scratch, updating it mainly based on the ESLint settings generated by the [sv create](https://svelte.dev/docs/cli/sv-create) command.
Additionally, I’ve adjusted the style of the documentation site. Since it’s planned to be migrated to Svelte’s official site later, it should be fine unless there’s something significantly wrong.

## MEMO

I need to handle https://github.com/sveltejs/eslint-plugin-svelte/pull/1043

pkg-pr-new[bot]: 
[Open in Stackblitz](https://pkg.pr.new/template/937d213b-f42e-4e7e-969e-f137d06f645c)


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


_commit: <a href="https://github.com/sveltejs/eslint-plugin-svelte/runs/36177033822"><code>4500081</code></a>_

changeset-bot[bot]: ###  ⚠️  No Changeset found

Latest commit: 759b9b5ea0a4f7e8297bfbe5c1b0d455133dc101

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. **If these changes should result in a version bump, you need to add a changeset.**

<details><summary>This PR includes no changesets</summary>

  When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

</details>

[Click here to learn what changesets are, and how to add one](https://github.com/changesets/changesets/blob/main/docs/adding-a-changeset.md).

[Click here if you're a maintainer who wants to add a changeset to this PR](https://github.com/sveltejs/eslint-plugin-svelte/new/chore/update-readme?filename=.changeset/forty-seas-destroy.md&value=---%0A%22eslint-plugin-svelte%22%3A%20patch%0A---%0A%0Achore%3A%20update%20README%20for%20v3%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%401041%22%7D#eslint-plugin-svelte%20with%20typescript)

## Install the Instant Preview to Your Local

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

## Published Instant Preview Packages:

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

[View Commit](https://github.com/sveltejs/eslint-plugin-svelte/commit/34a387bae8918ef462937dfa03bafdddb769f910)

Patch:
diff --git a/.changeset/gold-bottles-learn.md b/.changeset/gold-bottles-learn.md
new file mode 100644
index 0000000..2eb49d5
--- /dev/null
+++ b/.changeset/gold-bottles-learn.md
@@ -0,0 +1,5 @@
+---
+'eslint-plugin-svelte': patch
+---
+
+fix: allow `children` in `valid-prop-names-in-kit-pages` rule
diff --git a/.changeset/grumpy-files-design.md b/.changeset/grumpy-files-design.md
new file mode 100644
index 0000000..0f9c20e
--- /dev/null
+++ b/.changeset/grumpy-files-design.md
@@ -0,0 +1,5 @@
+---
+'eslint-plugin-svelte': major
+---
+
+breaking: remove `require-stores-init` from recommended rules
diff --git a/.changeset/hot-oranges-own.md b/.changeset/hot-oranges-own.md
new file mode 100644
index 0000000..49a4000
--- /dev/null
+++ b/.changeset/hot-oranges-own.md
@@ -0,0 +1,5 @@
+---
+"eslint-plugin-svelte": major
+---
+
+feat: add `*.svelte.{js,ts}` config to base config
diff --git a/.changeset/pre.json b/.changeset/pre.json
index 0052358..0d4d959 100644
--- a/.changeset/pre.json
+++ b/.changeset/pre.json
@@ -1,5 +1,5 @@
 {
-  "mode": "pre",
+  "mode": "exit",
   "tag": "next",
   "initialVersions": {
     "eslint-plugin-svelte": "2.46.0",
@@ -17,11 +17,13 @@
     "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",
diff --git a/.changeset/stupid-penguins-smoke.md b/.changeset/stupid-penguins-smoke.md
new file mode 100644
index 0000000..8be998d
--- /dev/null
+++ b/.changeset/stupid-penguins-smoke.md
@@ -0,0 +1,5 @@
+---
+'eslint-plugin-svelte': minor
+---
+
+feat: added the valid-style-parse rule
diff --git a/.changeset/tangy-monkeys-glow.md b/.changeset/tangy-monkeys-glow.md
new file mode 100644
index 0000000..8304ec1
--- /dev/null
+++ b/.changeset/tangy-monkeys-glow.md
@@ -0,0 +1,5 @@
+---
+'eslint-plugin-svelte': minor
+---
+
+chore: update `svelte-eslint-parser` to v1
diff --git a/.changeset/two-poets-wait.md b/.changeset/two-poets-wait.md
new file mode 100644
index 0000000..ff9a23c
--- /dev/null
+++ b/.changeset/two-poets-wait.md
@@ -0,0 +1,5 @@
+---
+'eslint-plugin-svelte': minor
+---
+
+feat: detect version information from node_modules when not specified in package.json, like pnpm’s catalog
diff --git a/.github/workflows/GHPages.yml b/.github/workflows/GHPages.yml
index d002776..d5a3e28 100644
--- a/.github/workflows/GHPages.yml
+++ b/.github/workflows/GHPages.yml
@@ -18,6 +18,7 @@ concurrency:
 
 jobs:
   deploy:
+    if: github.repository == 'sveltejs/eslint-plugin-svelte'
     environment:
       name: github-pages
       url: ${{ steps.deployment.outputs.page_url }}
diff --git a/.github/workflows/pkg.pr.new-comment.yml b/.github/workflows/pkg.pr.new-comment.yml
new file mode 100644
index 0000000..8ac14fa
--- /dev/null
+++ b/.github/workflows/pkg.pr.new-comment.yml
@@ -0,0 +1,32 @@
+name: Update pkg.pr.new comment
+
+on:
+  workflow_run:
+    workflows: ['Publish to pkg.pr.new']
+    types:
+      - completed
+
+jobs:
+  build:
+    if: github.repository == 'sveltejs/eslint-plugin-svelte'
+    name: 'Update comment'
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v4
+      - name: Download artifact
+        uses: actions/download-artifact@v4
+        with:
+          name: output
+          github-token: ${{ secrets.GITHUB_TOKEN }}
+          run-id: ${{ github.event.workflow_run.id }}
+      - run: ls -R .
+      - name: 'Post or update comment'
+        uses: actions/github-script@v7
+        with:
+          github-token: ${{ secrets.GITHUB_TOKEN }}
+          script: |
+            const fs = require('fs');
+            const output = JSON.parse(fs.readFileSync('output.json', 'utf8'));
+            const { default: process } = await import('${{ github.workspace }}/tools/pkg.pr.new-comment.mjs')
+
+            await process({github, context, core, output})
diff --git a/.github/workflows/pkg.pr.new.yml b/.github/workflows/pkg.pr.new.yml
index 2361397..cdb7776 100644
--- a/.github/workflows/pkg.pr.new.yml
+++ b/.github/workflows/pkg.pr.new.yml
@@ -8,6 +8,7 @@ on:
 
 jobs:
   build:
+    if: github.repository == 'sveltejs/eslint-plugin-svelte'
     runs-on: ubuntu-latest
 
     steps:
@@ -19,12 +20,24 @@ jobs:
       - name: Build
         run: pnpm run build
       - run: pnpx pkg-pr-new publish --compact './packages/eslint-plugin-svelte' --json output.json --comment=off
-      - uses: actions/github-script@v7
+      - name: Add metadata to output
+        uses: actions/github-script@v7
         with:
           github-token: ${{ secrets.GITHUB_TOKEN }}
           script: |
             const fs = require('fs');
             const output = JSON.parse(fs.readFileSync('output.json', 'utf8'));
-            const { default: process } = await import('${{ github.workspace }}/tools/pkg.pr.new-comment.mjs')
+            output.number = context.issue.number;
+            output.event_name = context.eventName;
+            output.ref = context.ref;
+            output.sha = context.eventName === 'pull_request'
+              ? context.payload.pull_request.head.sha
+              : context.payload.after;
+            fs.writeFileSync('output.json', JSON.stringify(output), 'utf8');
+      - name: Upload output
+        uses: actions/upload-artifact@v4
+        with:
+          name: output
+          path: ./output.json
 
-            await process({github, context, core, output})
+      - run: ls -R .
diff --git a/README.md b/README.md
index 01eb6bd..50140ce 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,217 @@ 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?
-
-[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
-
-The [svelte-eslint-parser] and the `eslint-plugin-svelte` can not be used with the [eslint-plugin-svelte3].
+<div align="center">
 
-[svelte-eslint-parser]: https://github.com/sveltejs/svelte-eslint-parser
-[eslint-plugin-svelte3]: https://github.com/sveltejs/eslint-plugin-svelte3
+# eslint-plugin-svelte
 
-#### Experimental support for Svelte v5
+## ESLint plugin for Svelte using AST
 
-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.
+[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)
 
-<!--DOCS_IGNORE_START-->
-
-## Versioning policy
+</div>
 
-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';
+// eslint.config.js
+import js from '@eslint/js';
+import svelte from 'eslint-plugin-svelte';
+import globals from 'globals';
+import svelteConfig from './svelte.config.js';
+
+/** @type {import('eslint').Linter.Config[]} */
 export default [
-  // add more generic rule sets here, such as:
-  // js.configs.recommended,
-  ...eslintPluginSvelte.configs.recommended,
+  js.configs.recommended,
+  ...svelte.configs.recommended,
+  {
+    languageOptions: {
+      globals: {
+        ...globals.browser,
+        ...globals.node // Add this if you are using SvelteKit in non-SPA mode
+      }
+    }
+  },
+  {
+    files: [
+      '*.svelte',
+      '**/*.svelte',
+      '*.svelte.ts',
+      '**/*.svelte.ts',
+      '*.svelte.js',
+      '**/*.svelte.js'
+    ],
+    languageOptions: {
+      parserOptions: {
+        // 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/add rules settings here, such as:
+      // Override or add rule 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.
+#### TypeScript project
 
-#### 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.
+```shell
+npm install --save-dev typescript-eslint
+```
 
 ```js
-import eslintPluginSvelte from 'eslint-plugin-svelte';
-import * as svelteParser from 'svelte-eslint-parser';
-import * as typescriptParser from '@typescript-eslint/parser';
-export default [
-  ...js.configs.recommended,
-  ...eslintPluginSvelte.configs.recommended,
+// 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 ts.config(
+  js.configs.recommended,
+  ...ts.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
       }
     }
-  }
-];
-```
-
-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'],
+    // See more details at: https://typescript-eslint.io/packages/parser/
     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']
+        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
+        // },
       }
     }
-  }
-];
-```
-
-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`
-
-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**:
-
-```js
-import eslintPluginSvelte from 'eslint-plugin-svelte';
-import svelteConfig from './svelte.config.js';
-export default [
-  ...eslintPluginSvelte.configs.recommended,
+  },
   {
     files: [
+      '*.svelte',
       '**/*.svelte',
-      '*.svelte'
-      // Add more files if you need.
-      // '**/*.svelte.ts', '*.svelte.ts', '**/*.svelte.js', '*.svelte.js',
+      '*.svelte.ts',
+      '**/*.svelte.ts',
+      '*.svelte.js',
+      '**/*.svelte.js'
     ],
     languageOptions: {
       parserOptions: {
-        // Specify the `svelte.config.js`.
+        // 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.
 
-You can change the behavior of this plugin with some settings.
+For more details, see [the rule list](https://sveltejs.github.io/eslint-plugin-svelte/rules/) to explore the rules provided by this plugin.
 
-e.g.
+### 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 +237,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
+## 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
 {
@@ -302,7 +252,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 in minor releases. If these new rules cause unwanted warnings, you can disable them.
+
+<!--DOCS_IGNORE_END-->
+
+## Rules
 
 <!-- prettier-ignore-start -->
 <!--RULES_SECTION_START-->
@@ -335,6 +295,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 +331,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 +414,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 830321a..6a67983 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",
@@ -39,13 +39,13 @@
     "assert": "^2.1.0",
     "cross-spawn": "^7.0.6",
     "env-cmd": "^10.1.0",
-    "esbuild": "^0.24.0",
+    "esbuild": "^0.25.0",
     "escape-html": "^1.0.3",
     "eslint-plugin-svelte": "workspace:^",
     "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",
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..732e2c8 100644
--- a/docs-svelte-kit/src/lib/sidemenu/UlMenu.svelte
+++ b/docs-svelte-kit/src/lib/sidemenu/UlMenu.svelte
@@ -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..1ec682f 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 in minor releases. If these new 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/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..eee703f
--- /dev/null
+++ b/docs/rules/valid-style-parse.md
@@ -0,0 +1,78 @@
+---
+pageClass: 'rule-details'
+sidebarDepth: 0
+title: 'svelte/valid-style-parse'
+description: 'require valid style element parsing'
+---
+
+# svelte/valid-style-parse
+
+> require valid style element parsing
+
+- :exclamation: <badge text="This rule has not been released yet." vertical="middle" type="error"> **_This rule has not been released yet._** </badge>
+
+## :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.
+
+## :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..9af837e 100644
--- a/docs/user-guide.md
+++ b/docs/user-guide.md
@@ -1,177 +1,195 @@
 # 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';
+// eslint.config.js
+import js from '@eslint/js';
+import svelte from 'eslint-plugin-svelte';
+import globals from 'globals';
+import svelteConfig from './svelte.config.js';
+
+/** @type {import('eslint').Linter.Config[]} */
 export default [
-  // add more generic rule sets here, such as:
-  // js.configs.recommended,
-  ...eslintPluginSvelte.configs.recommended,
+  js.configs.recommended,
+  ...svelte.configs.recommended,
+  {
+    languageOptions: {
+      globals: {
+        ...globals.browser,
+        ...globals.node // Add this if you are using SvelteKit in non-SPA mode
+      }
+    }
+  },
+  {
+    files: [
+      '*.svelte',
+      '**/*.svelte',
+      '*.svelte.ts',
+      '**/*.svelte.ts',
+      '*.svelte.js',
+      '**/*.svelte.js'
+    ],
+    languageOptions: {
+      parserOptions: {
+        // 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/add rules settings here, such as:
+      // Override or add rule 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.
+#### TypeScript project
 
-#### 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.
+```shell
+npm install --save-dev typescript-eslint
+```
 
 ```js
-import eslintPluginSvelte from 'eslint-plugin-svelte';
-import * as svelteParser from 'svelte-eslint-parser';
-import * as typescriptParser from '@typescript-eslint/parser';
-export default [
-  ...js.configs.recommended,
-  ...eslintPluginSvelte.configs.recommended,
+// 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 ts.config(
+  js.configs.recommended,
+  ...ts.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
       }
     }
-  }
-];
-```
-
-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'],
+    // See more details at: https://typescript-eslint.io/packages/parser/
     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']
+        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
+        // },
       }
     }
-  }
-];
-```
-
-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`
-
-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**:
-
-```js
-import eslintPluginSvelte from 'eslint-plugin-svelte';
-import svelteConfig from './svelte.config.js';
-export default [
-  ...eslintPluginSvelte.configs.recommended,
+  },
   {
     files: [
+      '*.svelte',
       '**/*.svelte',
-      '*.svelte'
-      // Add more files if you need.
-      // '**/*.svelte.ts', '*.svelte.ts', '**/*.svelte.js', '*.svelte.js',
+      '*.svelte.ts',
+      '**/*.svelte.ts',
+      '*.svelte.js',
+      '**/*.svelte.js'
     ],
     languageOptions: {
       parserOptions: {
-        // Specify the `svelte.config.js`.
+        // 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](./rules.md) 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'
@@ -184,59 +202,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
-
-### Visual Studio Code
-
-Use the [dbaeumer.vscode-eslint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) extension that Microsoft provides officially.
+## Editor Integrations
 
-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 +216,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 44892ce..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.4",
+  "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.19.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 47d0cf9..4d95e3c 100644
--- a/packages/eslint-plugin-svelte/CHANGELOG.md
+++ b/packages/eslint-plugin-svelte/CHANGELOG.md
@@ -1,5 +1,17 @@
 # eslint-plugin-svelte
 
+## 3.0.0-next.18
+
+### Patch Changes
+
+- [#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
+
+## 3.0.0-next.17
+
+### Major Changes
+
+- [#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
+
 ## 3.0.0-next.16
 
 ### Major Changes
diff --git a/packages/eslint-plugin-svelte/package.json b/packages/eslint-plugin-svelte/package.json
index daa1b09..c92d9ed 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.16",
+  "version": "3.0.0-next.18",
   "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",
@@ -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.0"
   },
   "devDependencies": {
     "@babel/core": "^7.26.0",
@@ -84,9 +84,9 @@
     "@types/stylus": "^0.48.43",
     "acorn": "^8.14.0",
     "assert": "^2.1.0",
-    "esbuild": "^0.24.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/base.ts b/packages/eslint-plugin-svelte/src/configs/flat/base.ts
index 7c74ffb..ee25fb2 100644
--- a/packages/eslint-plugin-svelte/src/configs/flat/base.ts
+++ b/packages/eslint-plugin-svelte/src/configs/flat/base.ts
@@ -34,6 +34,16 @@ const config: Linter.Config[] = [
 			'svelte/system': 'error'
 		},
 		processor: 'svelte/svelte'
+	},
+	{
+		name: 'svelte:base:setup-for-svelte-script',
+		files: ['*.svelte.js', '*.svelte.ts', '**/*.svelte.js', '**/*.svelte.ts'],
+		languageOptions: {
+			parser
+		},
+		rules: {
+			// eslint-plugin-svelte rules
+		}
 	}
 ];
 export default config;
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 20bdb22..8b63b17 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.16';
+export const version = '3.0.0-next.18';
diff --git a/packages/eslint-plugin-svelte/src/rule-types.ts b/packages/eslint-plugin-svelte/src/rule-types.ts
index 30f15c1..5e38cc0 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 ======= */
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 e846110..95cbe49 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
@@ -2,16 +2,22 @@ import type { AST } from 'svelte-eslint-parser';
 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';
 
 const EXPECTED_PROP_NAMES = ['data', 'errors', 'form', 'snapshot'];
+const EXPECTED_PROP_NAMES_SVELTE5 = [...EXPECTED_PROP_NAMES, 'children'];
 
-function checkProp(node: TSESTree.VariableDeclarator, context: RuleContext) {
+function checkProp(
+	node: TSESTree.VariableDeclarator,
+	context: RuleContext,
+	expectedPropNames: string[]
+) {
 	if (node.id.type !== 'ObjectPattern') return;
 	for (const p of node.id.properties) {
 		if (
 			p.type === 'Property' &&
 			p.value.type === 'Identifier' &&
-			!EXPECTED_PROP_NAMES.includes(p.value.name)
+			!expectedPropNames.includes(p.value.name)
 		) {
 			context.report({
 				node: p.value,
@@ -42,6 +48,8 @@ export default createRule('valid-prop-names-in-kit-pages', {
 	},
 	create(context) {
 		let isScript = false;
+		const isSvelte5 = getSvelteVersion() === '5';
+		const expectedPropNames = isSvelte5 ? EXPECTED_PROP_NAMES_SVELTE5 : EXPECTED_PROP_NAMES;
 		return {
 			// <script>
 			'Program > SvelteScriptElement > SvelteStartTag': (node: AST.SvelteStartTag) => {
@@ -67,7 +75,7 @@ export default createRule('valid-prop-names-in-kit-pages', {
 
 				// export let foo
 				if (node.id.type === 'Identifier') {
-					if (!EXPECTED_PROP_NAMES.includes(node.id.name)) {
+					if (!expectedPropNames.includes(node.id.name)) {
 						context.report({
 							node,
 							loc: node.loc,
@@ -78,7 +86,7 @@ export default createRule('valid-prop-names-in-kit-pages', {
 				}
 
 				// export let { xxx, yyy } = zzz
-				checkProp(node, context);
+				checkProp(node, context, expectedPropNames);
 			},
 
 			// Svelte5
@@ -93,7 +101,7 @@ export default createRule('valid-prop-names-in-kit-pages', {
 					return;
 				}
 
-				checkProp(node, context);
+				checkProp(node, context, expectedPropNames);
 			}
 		};
 	}
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 42c5562..e4cb124 100644
--- a/packages/eslint-plugin-svelte/src/utils/svelte-context.ts
+++ b/packages/eslint-plugin-svelte/src/utils/svelte-context.ts
@@ -2,7 +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;
 
@@ -96,23 +99,51 @@ function getSvelteKitFileTypeFromFilePath(filePath: string): SvelteContext['svel
 	}
 }
 
+function extractMajorVersion(version: string, recognizePrereleaseVersion: boolean): string | null {
+	if (recognizePrereleaseVersion) {
+		const match = /^(?:\^|~)?(\d+\.0\.0-next)/.exec(version);
+		if (match && match[1]) {
+			return match[1];
+		}
+	}
+
+	const match = /^(?:\^|~)?(\d+)\./.exec(version);
+	if (match && match[1]) {
+		return match[1];
+	}
+	return null;
+}
+
+const svelteKitContextCache = createCache<Pick<
+	SvelteContext,
+	'svelteKitFileType' | 'svelteKitVersion'
+> | null>();
+
 function getSvelteKitContext(
 	context: RuleContext
 ): Pick<SvelteContext, 'svelteKitFileType' | 'svelteKitVersion'> {
 	const filePath = getFilename(context);
+
+	const cached = svelteKitContextCache.get(filePath);
+	if (cached) return cached;
+
 	const svelteKitVersion = getSvelteKitVersion(filePath);
 	if (svelteKitVersion == null) {
-		return {
+		const result: Pick<SvelteContext, 'svelteKitFileType' | 'svelteKitVersion'> = {
 			svelteKitFileType: null,
 			svelteKitVersion: null
 		};
+		svelteKitContextCache.set(filePath, result);
+		return result;
 	}
 	if (isRunInBrowser) {
-		return {
+		const result: Pick<SvelteContext, 'svelteKitFileType' | 'svelteKitVersion'> = {
 			svelteKitVersion,
 			// Judge by only file path if it runs in browser.
 			svelteKitFileType: getSvelteKitFileTypeFromFilePath(filePath)
 		};
+		svelteKitContextCache.set(filePath, result);
+		return result;
 	}
 
 	const routes =
@@ -123,92 +154,109 @@ function getSvelteKitContext(
 	const projectRootDir = getProjectRootDir(getFilename(context)) ?? '';
 
 	if (!filePath.startsWith(path.join(projectRootDir, routes))) {
-		return {
+		const result: Pick<SvelteContext, 'svelteKitFileType' | 'svelteKitVersion'> = {
 			svelteKitVersion,
 			svelteKitFileType: null
 		};
+		svelteKitContextCache.set(filePath, result);
+		return result;
 	}
 
-	return {
+	const result: Pick<SvelteContext, 'svelteKitFileType' | 'svelteKitVersion'> = {
 		svelteKitVersion,
 		svelteKitFileType: getSvelteKitFileTypeFromFilePath(filePath)
 	};
+	svelteKitContextCache.set(filePath, result);
+	return result;
 }
 
-function getSvelteVersion(filePath: string): SvelteContext['svelteVersion'] {
+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) 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') {
-				return '3/4';
-			}
-			return major as SvelteContext['svelteVersion'];
-		}
-	} catch {
-		/** do nothing */
+	if (isRunInBrowser) {
+		return '5';
 	}
 
-	return null;
+	return checkAndSetSvelteVersion(SVELTE_VERSION);
+}
+
+const svelteKitVersionCache = createCache<SvelteContext['svelteKitVersion']>();
+
+function checkAndSetSvelteKitVersion(
+	version: string,
+	filePath: string
+): SvelteContext['svelteKitVersion'] {
+	const major = extractMajorVersion(version, true) as SvelteContext['svelteKitVersion'];
+	svelteKitVersionCache.set(filePath, major);
+	return major;
 }
 
-/**
- * Check givin file is under SvelteKit project.
- *
- * If it runs on browser, it always returns true.
- *
- * @param filePath A file path.
- * @returns
- */
 function getSvelteKitVersion(filePath: string): SvelteContext['svelteKitVersion'] {
+	const cached = svelteKitVersionCache.get(filePath);
+	if (cached) return cached;
+
 	// Hack: if it runs in browser, it regards as SvelteKit project.
-	if (isRunInBrowser) return '2';
-	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.
-			return '2';
+	if (isRunInBrowser) {
+		svelteKitVersionCache.set(filePath, '2');
+		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 */
 		}
+	}
 
-		for (const packageJson of packageJsons) {
-			const version =
-				packageJson.dependencies?.['@sveltejs/kit'] ??
-				packageJson.devDependencies?.['@sveltejs/kit'];
-			if (typeof version !== 'string') {
-				return null;
+	try {
+		const packageJsons = getPackageJsons(filePath);
+		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';
 			}
 
-			return extractMajorVersion(version, true) as SvelteContext['svelteKitVersion'];
+			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;
+					}
+				}
+			}
 		}
 	} catch {
 		/** do nothing */
 	}
 
+	svelteKitVersionCache.set(filePath, null);
 	return null;
 }
 
-function extractMajorVersion(version: string, recognizePrereleaseVersion: boolean): string | null {
-	if (recognizePrereleaseVersion) {
-		const match = /^(?:\^|~)?(\d+\.0\.0-next)/.exec(version);
-		if (match && match[1]) {
-			return match[1];
-		}
-	}
-
-	const match = /^(?:\^|~)?(\d+)\./.exec(version);
-	if (match && match[1]) {
-		return match[1];
-	}
-	return null;
-}
+const projectRootDirCache = createCache<string | null>();
 
 /**
  * Gets a  project root folder path.
@@ -217,58 +265,81 @@ function extractMajorVersion(version: string, recognizePrereleaseVersion: boolea
  */
 function getProjectRootDir(filePath: string): string | null {
 	if (isRunInBrowser) return null;
+	const cached = projectRootDirCache.get(filePath);
+	if (cached) return cached;
+
 	const packageJsons = getPackageJsons(filePath);
 	if (packageJsons.length === 0) {
+		projectRootDirCache.set(filePath, null);
 		return null;
 	}
 	const packageJsonFilePath = packageJsons[0].filePath;
-	if (!packageJsonFilePath) return null;
-	return path.dirname(path.resolve(packageJsonFilePath));
+	if (!packageJsonFilePath) {
+		projectRootDirCache.set(filePath, null);
+		return null;
+	}
+	const projectRootDir = path.dirname(path.resolve(packageJsonFilePath));
+	projectRootDirCache.set(filePath, projectRootDir);
+	return projectRootDir;
 }
 
+const svelteContextCache = createCache<SvelteContext | null>();
+
 export function getSvelteContext(context: RuleContext): SvelteContext | null {
 	const { parserServices } = getSourceCode(context);
 	const { svelteParseContext } = parserServices;
 	const filePath = getFilename(context);
+
+	const cached = svelteContextCache.get(filePath);
+	if (cached) return cached;
+
 	const svelteKitContext = getSvelteKitContext(context);
-	const svelteVersion = getSvelteVersion(filePath);
+	const svelteVersion = getSvelteVersion();
 	const svelteFileType = getSvelteFileType(filePath);
 
 	if (svelteVersion == null) {
-		return {
+		const result: SvelteContext = {
 			svelteVersion: null,
 			svelteFileType: null,
 			runes: null,
 			svelteKitVersion: svelteKitContext.svelteKitVersion,
 			svelteKitFileType: svelteKitContext.svelteKitFileType
 		};
+		svelteContextCache.set(filePath, result);
+		return result;
 	}
 
 	if (svelteVersion === '3/4') {
-		return {
+		const result: SvelteContext = {
 			svelteVersion,
 			svelteFileType: svelteFileType === '.svelte' ? '.svelte' : null,
 			runes: null,
 			svelteKitVersion: svelteKitContext.svelteKitVersion,
 			svelteKitFileType: svelteKitContext.svelteKitFileType
 		};
+		svelteContextCache.set(filePath, result);
+		return result;
 	}
 
 	if (svelteFileType == null) {
-		return {
+		const result: SvelteContext = {
 			svelteVersion,
 			svelteFileType: null,
 			runes: null,
 			svelteKitVersion: svelteKitContext.svelteKitVersion,
 			svelteKitFileType: svelteKitContext.svelteKitFileType
 		};
+		svelteContextCache.set(filePath, result);
+		return result;
 	}
 
-	return {
+	const result: SvelteContext = {
 		svelteVersion,
 		runes: svelteParseContext?.runes ?? 'undetermined',
 		svelteFileType,
 		svelteKitVersion: svelteKitContext.svelteKitVersion,
 		svelteKitFileType: svelteKitContext.svelteKitFileType
 	};
+	svelteContextCache.set(filePath, result);
+	return result;
 }
diff --git a/packages/eslint-plugin-svelte/tools/update-rulesets.ts b/packages/eslint-plugin-svelte/tools/update-rulesets.ts
index 1431662..cdbcf4b 100644
--- a/packages/eslint-plugin-svelte/tools/update-rulesets.ts
+++ b/packages/eslint-plugin-svelte/tools/update-rulesets.ts
@@ -20,38 +20,61 @@ export function setPluginObject(plugin: ESLint.Plugin): void {
 	pluginObject = plugin;
 }
 const config: Linter.Config[] = [
-  {
-    name: 'svelte:base:setup-plugin',
-    plugins: {
-      get svelte(): ESLint.Plugin {
-        return pluginObject!;
-      }
-    },
-  },
-  {
-    name: 'svelte:base:setup-for-svelte',
-    files: ["*.svelte", "**/*.svelte"],
-    languageOptions: {
-      parser: parser,
-    },
-    rules: {
-      // ESLint core rules known to cause problems with \`.svelte\`.
-      "no-inner-declarations": "off", // The AST generated by svelte-eslint-parser will false positives in it rule because the root node of the script is not the \`Program\`.
-      // "no-irregular-whitespace": "off",
-      // Self assign is one of way to update reactive value in Svelte.
-      "no-self-assign": "off",
+	{
+		name: 'svelte:base:setup-plugin',
+		plugins: {
+			get svelte(): ESLint.Plugin {
+				return pluginObject!;
+			}
+		},
+	},
+	{
+		name: 'svelte:base:setup-for-svelte',
+		files: ["*.svelte", "**/*.svelte"],
+		languageOptions: {
+			parser: parser,
+		},
+		rules: {
+			// ESLint core rules known to cause problems with \`.svelte\`.
+			"no-inner-declarations": "off", // The AST generated by svelte-eslint-parser will false positives in it rule because the root node of the script is not the \`Program\`.
+			// "no-irregular-whitespace": "off",
+			// Self assign is one of way to update reactive value in Svelte.
+			"no-self-assign": "off",
 
-      // eslint-plugin-svelte rules
-      ${rules
+			// eslint-plugin-svelte rules
+			${rules
 				.filter((rule) => rule.meta.docs.recommended === 'base' && !rule.meta.deprecated)
 				.map((rule) => {
 					const conf = rule.meta.docs.default || 'error';
 					return `"${rule.meta.docs.ruleId}": "${conf}"`;
 				})
-				.join(',\n        ')},
-    },
+				.join(',\n			')}
+		},
 		processor: 'svelte/svelte'
-  },
+	},
+	{
+		name: 'svelte:base:setup-for-svelte-script',
+		files: ['*.svelte.js', '*.svelte.ts', '**/*.svelte.js', '**/*.svelte.ts'],
+		languageOptions: {
+			parser: parser,
+		},
+		rules: {
+			// eslint-plugin-svelte rules
+			${rules
+				.filter((rule) => rule.meta.docs.recommended === 'base' && !rule.meta.deprecated)
+				.filter(
+					// Exclude rules that are not applicable to JavaScript files
+					(rule) =>
+						rule.meta.docs.ruleId !== 'svelte/comment-directive' &&
+						rule.meta.docs.ruleId !== 'svelte/system'
+				)
+				.map((rule) => {
+					const conf = rule.meta.docs.default || 'error';
+					return `"${rule.meta.docs.ruleId}": "${conf}"`;
+				})
+				.join(',\n			')}
+		},
+	}
 ]
 export default config
 `;
@@ -69,20 +92,20 @@ const recommendedContent = `/*
 import type { Linter } from 'eslint';
 import base from "./base.js"
 const config: Linter.Config[] = [
-  ...base,
-  {
-    name: 'svelte:recommended:rules',
-    rules: {
-      // eslint-plugin-svelte rules
-      ${rules
+	...base,
+	{
+		name: 'svelte:recommended:rules',
+		rules: {
+			// eslint-plugin-svelte rules
+			${rules
 				.filter((rule) => rule.meta.docs.recommended && !rule.meta.deprecated)
 				.map((rule) => {
 					const conf = rule.meta.docs.default || 'error';
 					return `"${rule.meta.docs.ruleId}": "${conf}"`;
 				})
-				.join(',\n    ')},
-    },
-  }
+				.join(',\n			')},
+		},
+	}
 ]
 export default config
 `;
@@ -100,17 +123,17 @@ const prettierContent = `/*
 import type { Linter } from 'eslint';
 import base from "./base.js"
 const config: Linter.Config[] = [
-  ...base,
-  {
-    name: 'svelte:prettier:turn-off-rules',
-    rules: {
-      // eslint-plugin-svelte rules
-      ${rules
+	...base,
+	{
+		name: 'svelte:prettier:turn-off-rules',
+		rules: {
+			// eslint-plugin-svelte rules
+			${rules
 				.filter((rule) => rule.meta.docs.conflictWithPrettier)
 				.map((rule) => `"${rule.meta.docs.ruleId}": "off"`)
-				.join(',\n    ')},
-    },
-  }
+				.join(',\n			')},
+		},
+	}
 ]
 export default config
 `;
diff --git a/tools/pkg.pr.new-comment.mjs b/tools/pkg.pr.new-comment.mjs
index 689971e..bbf6a75 100644
--- a/tools/pkg.pr.new-comment.mjs
+++ b/tools/pkg.pr.new-comment.mjs
@@ -2,42 +2,39 @@
  * Used in `/.github/workflows/pkg.pr.new.yml`
  */
 export default async function ({ github, context, output }) {
-  // eslint-disable-next-line no-console -- For debugging on github actions.
-  console.log("pkg-pr-new publish output:", JSON.stringify(output));
-
-  const sha =
-    context.eventName === "pull_request"
-      ? context.payload.pull_request.head.sha
-      : context.payload.after;
-  const commitUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/commit/${sha}`;
-
-  const pullRequestNumber = await getPullRequestNumber();
-
-  const packages = output.packages.map((p) => {
-    let normalizedUrl = p.url;
-    if (pullRequestNumber && p.url.endsWith(sha)) {
-      normalizedUrl = `${p.url.slice(0, -sha.length)}${pullRequestNumber}`;
-    }
-    const repoPath = `/${context.repo.owner}/${context.repo.repo}/`;
-    normalizedUrl = normalizedUrl.replace(repoPath, "/");
-
-    return {
-      name: p.name,
-      url: normalizedUrl,
-    };
-  });
-
-  const botCommentIdentifier = "<!-- posted by pkg.pr.new-comment.mjs -->";
-
-  const onlineUrl = new URL(
-    "https://eslint-online-playground.netlify.app/#eslint-plugin-svelte%20with%20typescript",
-  );
-  const overrideDeps = {};
-  for (const p of packages) {
-    overrideDeps[p.name] = p.url;
-  }
-  onlineUrl.searchParams.set("overrideDeps", JSON.stringify(overrideDeps));
-  const body = `${botCommentIdentifier}
+	// eslint-disable-next-line no-console -- For debugging on github actions.
+	console.log('pkg-pr-new publish output:', JSON.stringify(output));
+
+	const sha = output.sha;
+	const commitUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/commit/${sha}`;
+
+	const pullRequestNumber = await getPullRequestNumber();
+
+	const packages = output.packages.map((p) => {
+		let normalizedUrl = p.url;
+		if (pullRequestNumber && p.url.endsWith(sha)) {
+			normalizedUrl = `${p.url.slice(0, -sha.length)}${pullRequestNumber}`;
+		}
+		const repoPath = `/${context.repo.owner}/${context.repo.repo}/`;
+		normalizedUrl = normalizedUrl.replace(repoPath, '/');
+
+		return {
+			name: p.name,
+			url: normalizedUrl
+		};
+	});
+
+	const botCommentIdentifier = '<!-- posted by pkg.pr.new-comment.mjs -->';
+
+	const onlineUrl = new URL(
+		'https://eslint-online-playground.netlify.app/#eslint-plugin-svelte%20with%20typescript'
+	);
+	const overrideDeps = {};
+	for (const p of packages) {
+		overrideDeps[p.name] = p.url;
+	}
+	onlineUrl.searchParams.set('overrideDeps', JSON.stringify(overrideDeps));
+	const body = `${botCommentIdentifier}
 
 ## Try the Instant Preview in Online Playground
 
@@ -46,79 +43,61 @@ export default async function ({ github, context, output }) {
 ## Install the Instant Preview to Your Local
 
 \`\`\`
-npm i ${packages.map((p) => p.url).join(" ")}
+npm i ${packages.map((p) => p.url).join(' ')}
 \`\`\`
 
 ## Published Instant Preview Packages:
 
-${packages.map((p) => `- ${p.name}: ${p.url}`).join("\n")}
+${packages.map((p) => `- ${p.name}: ${p.url}`).join('\n')}
 
 [View Commit](${commitUrl})`;
 
-  if (pullRequestNumber) {
-    await createOrUpdateComment(pullRequestNumber);
-  } else {
-    /* eslint-disable no-console -- For debugging on github actions. */
-    console.log(
-      "No open pull request found for this push. Logging publish information to console:",
-    );
-    console.log(`\n${"=".repeat(50)}`);
-    console.log(body);
-    console.log(`\n${"=".repeat(50)}`);
-    /* eslint-enable no-console -- For debugging on github actions. */
-  }
-
-  async function getPullRequestNumber() {
-    if (context.eventName === "pull_request") {
-      if (context.issue.number) {
-        return context.issue.number;
-      }
-    } else if (context.eventName === "push") {
-      const pullRequests = await github.rest.pulls.list({
-        owner: context.repo.owner,
-        repo: context.repo.repo,
-        state: "open",
-        head: `${context.repo.owner}:${context.ref.replace("refs/heads/", "")}`,
-      });
-
-      if (pullRequests.data.length > 0) {
-        return pullRequests.data[0].number;
-      }
-    }
-    return null;
-  }
-
-  async function findBotComment(issueNumber) {
-    if (!issueNumber) return null;
-    const comments = await github.rest.issues.listComments({
-      owner: context.repo.owner,
-      repo: context.repo.repo,
-      // eslint-disable-next-line camelcase -- The ID defined in the GitHub API.
-      issue_number: issueNumber,
-    });
-    return comments.data.find((comment) =>
-      comment.body.includes(botCommentIdentifier),
-    );
-  }
-
-  async function createOrUpdateComment(issueNumber) {
-    const existingComment = await findBotComment(issueNumber);
-    if (existingComment) {
-      await github.rest.issues.updateComment({
-        owner: context.repo.owner,
-        repo: context.repo.repo,
-        // eslint-disable-next-line camelcase -- The ID defined in the GitHub API.
-        comment_id: existingComment.id,
-        body,
-      });
-    } else {
-      await github.rest.issues.createComment({
-        // eslint-disable-next-line camelcase -- The ID defined in the GitHub API.
-        issue_number: issueNumber,
-        owner: context.repo.owner,
-        repo: context.repo.repo,
-        body,
-      });
-    }
-  }
+	if (pullRequestNumber) {
+		await createOrUpdateComment(pullRequestNumber);
+	} else {
+		/* eslint-disable no-console -- For debugging on github actions. */
+		console.log(
+			'No open pull request found for this push. Logging publish information to console:'
+		);
+		console.log(`\n${'='.repeat(50)}`);
+		console.log(body);
+		console.log(`\n${'='.repeat(50)}`);
+		/* eslint-enable no-console -- For debugging on github actions. */
+	}
+
+	async function getPullRequestNumber() {
+		return output.number;
+	}
+
+	async function findBotComment(issueNumber) {
+		if (!issueNumber) return null;
+		const comments = await github.rest.issues.listComments({
+			owner: context.repo.owner,
+			repo: context.repo.repo,
+			// eslint-disable-next-line camelcase -- The ID defined in the GitHub API.
+			issue_number: issueNumber
+		});
+		return comments.data.find((comment) => comment.body.includes(botCommentIdentifier));
+	}
+
+	async function createOrUpdateComment(issueNumber) {
+		const existingComment = await findBotComment(issueNumber);
+		if (existingComment) {
+			await github.rest.issues.updateComment({
+				owner: context.repo.owner,
+				repo: context.repo.repo,
+				// eslint-disable-next-line camelcase -- The ID defined in the GitHub API.
+				comment_id: existingComment.id,
+				body
+			});
+		} else {
+			await github.rest.issues.createComment({
+				// eslint-disable-next-line camelcase -- The ID defined in the GitHub API.
+				issue_number: issueNumber,
+				owner: context.repo.owner,
+				repo: context.repo.repo,
+				body
+			});
+		}
+	}
 }


Test patch:
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/invalid/svelte4-children/+page.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/invalid/svelte4-children/+page.svelte
new file mode 100644
index 0000000..eb660d7
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/invalid/svelte4-children/+page.svelte
@@ -0,0 +1,5 @@
+<script>
+	export let children;
+</script>
+
+{children}
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/invalid/svelte4-children/_config.json b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/invalid/svelte4-children/_config.json
new file mode 100644
index 0000000..7e9bb8b
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/invalid/svelte4-children/_config.json
@@ -0,0 +1,13 @@
+{
+	"languageOptions": {
+		"parserOptions": {
+			"svelteConfig": {
+				"kit": {
+					"files": {
+						"routes": "tests/fixtures/rules/valid-prop-names-in-kit-pages/invalid/svelte4-children"
+					}
+				}
+			}
+		}
+	}
+}
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/invalid/svelte4-children/errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/invalid/svelte4-children/errors.yaml
new file mode 100644
index 0000000..1d3d857
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/invalid/svelte4-children/errors.yaml
@@ -0,0 +1,4 @@
+- message: disallow props other than data or errors in SvelteKit page components.
+  line: 2
+  column: 13
+  suggestions: null
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/invalid/svelte4-children/requirements.json b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/invalid/svelte4-children/requirements.json
new file mode 100644
index 0000000..b650cc2
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/invalid/svelte4-children/requirements.json
@@ -0,0 +1,3 @@
+{
+	"svelte": "^3.0.0 || ^4.0.0"
+}
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/svelte5-without-runes/+page.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/svelte5-without-runes/+page.svelte
new file mode 100644
index 0000000..b1fd594
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/svelte5-without-runes/+page.svelte
@@ -0,0 +1,24 @@
+<script>
+	export let data;
+	export let errors;
+	export let form;
+	export let children;
+
+	let comment = '';
+
+	export const snapshot = {
+		capture: () => comment,
+		restore: (value) => (comment = value)
+	};
+</script>
+
+{data}, {errors}
+
+{#if form?.success}
+	<p>Successfully logged in! Welcome back, {data.user.name}</p>
+{/if}
+
+<form method="POST">
+	<textarea bind:value={comment} />
+	<button>Post comment</button>
+</form>
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/svelte5-without-runes/_config.json b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/svelte5-without-runes/_config.json
new file mode 100644
index 0000000..e245d26
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/svelte5-without-runes/_config.json
@@ -0,0 +1,13 @@
+{
+	"languageOptions": {
+		"parserOptions": {
+			"svelteConfig": {
+				"kit": {
+					"files": {
+						"routes": "tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/svelte5-without-runes"
+					}
+				}
+			}
+		}
+	}
+}
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/svelte5-without-runes/requirements.json b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/svelte5-without-runes/requirements.json
new file mode 100644
index 0000000..0192b10
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/svelte5-without-runes/requirements.json
@@ -0,0 +1,3 @@
+{
+	"svelte": ">=5.0.0-0"
+}
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/svelte5/+page.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/svelte5/+page.svelte
index 6ed2875..6672340 100644
--- a/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/svelte5/+page.svelte
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/valid-prop-names-in-kit-pages/valid/svelte5/+page.svelte
@@ -1,5 +1,5 @@
 <script>
-	let { data, errors, form } = $props();
+	let { data, errors, form, children } = $props();
 
 	let comment = '';
 
@@ -18,4 +18,5 @@
 <form method="POST">
 	<textarea bind:value={comment} />
 	<button>Post comment</button>
+	{@render children()}
 </form>
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'));