diff --git a/.changeset/hip-tips-smell.md b/.changeset/hip-tips-smell.md
new file mode 100644
index 000000000..60dd0cd3b
--- /dev/null
+++ b/.changeset/hip-tips-smell.md
@@ -0,0 +1,5 @@
+---
+"eslint-plugin-svelte": minor
+---
+
+feat: add new `svelte/no-ignored-unsubscribe` rule.
diff --git a/README.md b/README.md
index 80f6f903f..7df272aa1 100644
--- a/README.md
+++ b/README.md
@@ -340,6 +340,7 @@ These rules relate to better ways of doing things to help you avoid problems:
| [svelte/block-lang](https://sveltejs.github.io/eslint-plugin-svelte/rules/block-lang/) | disallows the use of languages other than those specified in the configuration for the lang attribute of `
+```
+
+
+
+## :wrench: Options
+
+Nothing.
+
+## :mag: Implementation
+
+- [Rule source](https://github.com/sveltejs/eslint-plugin-svelte/blob/main/src/rules/no-ignored-unsubscribe.ts)
+- [Test source](https://github.com/sveltejs/eslint-plugin-svelte/blob/main/tests/src/rules/no-ignored-unsubscribe.ts)
diff --git a/src/rules/no-ignored-unsubscribe.ts b/src/rules/no-ignored-unsubscribe.ts
new file mode 100644
index 000000000..471f38a36
--- /dev/null
+++ b/src/rules/no-ignored-unsubscribe.ts
@@ -0,0 +1,32 @@
+import type { TSESTree } from '@typescript-eslint/types';
+import { createRule } from '../utils';
+
+export default createRule('no-ignored-unsubscribe', {
+ meta: {
+ docs: {
+ description:
+ 'disallow ignoring the unsubscribe method returned by the `subscribe()` on Svelte stores.',
+ category: 'Best Practices',
+ recommended: false
+ },
+ fixable: undefined,
+ hasSuggestions: false,
+ messages: {
+ forbidden: 'Ignoring returned value of the subscribe method is forbidden.'
+ },
+ schema: [],
+ type: 'problem'
+ },
+ create: (context) => {
+ return {
+ "ExpressionStatement > CallExpression > MemberExpression.callee[property.name='subscribe']": (
+ node: TSESTree.MemberExpression
+ ) => {
+ context.report({
+ messageId: 'forbidden',
+ node: node.property
+ });
+ }
+ };
+ }
+});
diff --git a/src/utils/rules.ts b/src/utils/rules.ts
index f1181de8d..c496dec7b 100644
--- a/src/utils/rules.ts
+++ b/src/utils/rules.ts
@@ -27,6 +27,7 @@ import noDupeUseDirectives from '../rules/no-dupe-use-directives';
import noDynamicSlotName from '../rules/no-dynamic-slot-name';
import noExportLoadInSvelteModuleInKitPages from '../rules/no-export-load-in-svelte-module-in-kit-pages';
import noExtraReactiveCurlies from '../rules/no-extra-reactive-curlies';
+import noIgnoredUnsubscribe from '../rules/no-ignored-unsubscribe';
import noImmutableReactiveStatements from '../rules/no-immutable-reactive-statements';
import noInnerDeclarations from '../rules/no-inner-declarations';
import noNotFunctionHandler from '../rules/no-not-function-handler';
@@ -88,6 +89,7 @@ export const rules = [
noDynamicSlotName,
noExportLoadInSvelteModuleInKitPages,
noExtraReactiveCurlies,
+ noIgnoredUnsubscribe,
noImmutableReactiveStatements,
noInnerDeclarations,
noNotFunctionHandler,
diff --git a/tests/fixtures/rules/no-ignored-unsubscribe/invalid/test01-errors.yaml b/tests/fixtures/rules/no-ignored-unsubscribe/invalid/test01-errors.yaml
new file mode 100644
index 000000000..9b0c1ee4c
--- /dev/null
+++ b/tests/fixtures/rules/no-ignored-unsubscribe/invalid/test01-errors.yaml
@@ -0,0 +1,4 @@
+- message: Ignoring returned value of the subscribe method is forbidden.
+ line: 6
+ column: 6
+ suggestions: null
diff --git a/tests/fixtures/rules/no-ignored-unsubscribe/invalid/test01-input.svelte b/tests/fixtures/rules/no-ignored-unsubscribe/invalid/test01-input.svelte
new file mode 100644
index 000000000..47f230d91
--- /dev/null
+++ b/tests/fixtures/rules/no-ignored-unsubscribe/invalid/test01-input.svelte
@@ -0,0 +1,9 @@
+
diff --git a/tests/fixtures/rules/no-ignored-unsubscribe/valid/test01-input.svelte b/tests/fixtures/rules/no-ignored-unsubscribe/valid/test01-input.svelte
new file mode 100644
index 000000000..f4f68b2df
--- /dev/null
+++ b/tests/fixtures/rules/no-ignored-unsubscribe/valid/test01-input.svelte
@@ -0,0 +1,9 @@
+
diff --git a/tests/fixtures/rules/no-ignored-unsubscribe/valid/test02-input.svelte b/tests/fixtures/rules/no-ignored-unsubscribe/valid/test02-input.svelte
new file mode 100644
index 000000000..e255f63c4
--- /dev/null
+++ b/tests/fixtures/rules/no-ignored-unsubscribe/valid/test02-input.svelte
@@ -0,0 +1,12 @@
+
diff --git a/tests/fixtures/rules/no-ignored-unsubscribe/valid/test03-input.svelte b/tests/fixtures/rules/no-ignored-unsubscribe/valid/test03-input.svelte
new file mode 100644
index 000000000..19615225d
--- /dev/null
+++ b/tests/fixtures/rules/no-ignored-unsubscribe/valid/test03-input.svelte
@@ -0,0 +1,3 @@
+
diff --git a/tests/src/rules/no-ignored-unsubscribe.ts b/tests/src/rules/no-ignored-unsubscribe.ts
new file mode 100644
index 000000000..2d3bd2d3e
--- /dev/null
+++ b/tests/src/rules/no-ignored-unsubscribe.ts
@@ -0,0 +1,12 @@
+import { RuleTester } from 'eslint';
+import rule from '../../../src/rules/no-ignored-unsubscribe';
+import { loadTestCases } from '../../utils/utils';
+
+const tester = new RuleTester({
+ parserOptions: {
+ ecmaVersion: 2020,
+ sourceType: 'module'
+ }
+});
+
+tester.run('no-ignored-unsubscribe', rule as any, loadTestCases('no-ignored-unsubscribe'));