diff --git a/README.md b/README.md
index f0a95ec47..9cbc2bde5 100644
--- a/README.md
+++ b/README.md
@@ -282,6 +282,7 @@ These rules relate to better ways of doing things to help you avoid problems:
|:--------|:------------|:---|
| [svelte/button-has-type](https://ota-meshi.github.io/eslint-plugin-svelte/rules/button-has-type/) | disallow usage of button without an explicit type attribute | |
| [svelte/no-at-debug-tags](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-at-debug-tags/) | disallow the use of `{@debug}` | :star: |
+| [svelte/no-reactive-functions](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-reactive-functions/) | It's not necessary to define functions in reactive statements | :bulb: |
| [svelte/no-reactive-literals](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-reactive-literals/) | Don't assign literal values in reactive statements | :bulb: |
| [svelte/no-unused-svelte-ignore](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-unused-svelte-ignore/) | disallow unused svelte-ignore comments | :star: |
| [svelte/no-useless-mustaches](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-useless-mustaches/) | disallow unnecessary mustache interpolations | :wrench: |
diff --git a/docs/rules.md b/docs/rules.md
index 407aa65d5..8145ffbee 100644
--- a/docs/rules.md
+++ b/docs/rules.md
@@ -42,6 +42,7 @@ These rules relate to better ways of doing things to help you avoid problems:
|:--------|:------------|:---|
| [svelte/button-has-type](./rules/button-has-type.md) | disallow usage of button without an explicit type attribute | |
| [svelte/no-at-debug-tags](./rules/no-at-debug-tags.md) | disallow the use of `{@debug}` | :star: |
+| [svelte/no-reactive-functions](./rules/no-reactive-functions.md) | It's not necessary to define functions in reactive statements | :bulb: |
| [svelte/no-reactive-literals](./rules/no-reactive-literals.md) | Don't assign literal values in reactive statements | :bulb: |
| [svelte/no-unused-svelte-ignore](./rules/no-unused-svelte-ignore.md) | disallow unused svelte-ignore comments | :star: |
| [svelte/no-useless-mustaches](./rules/no-useless-mustaches.md) | disallow unnecessary mustache interpolations | :wrench: |
diff --git a/docs/rules/no-reactive-functions.md b/docs/rules/no-reactive-functions.md
new file mode 100644
index 000000000..c25c758e0
--- /dev/null
+++ b/docs/rules/no-reactive-functions.md
@@ -0,0 +1,52 @@
+---
+pageClass: "rule-details"
+sidebarDepth: 0
+title: "svelte/no-reactive-functions"
+description: "It's not necessary to define functions in reactive statements"
+---
+
+# svelte/no-reactive-functions
+
+> It's not necessary to define functions in reactive statements
+
+- :exclamation: **_This rule has not been released yet._**
+- :bulb: Some problems reported by this rule are manually fixable by editor [suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions).
+
+## :book: Rule Details
+
+This rule reports whenever a function is defined in a reactive statement. This isn't necessary, as each time the function is executed it'll already have access to the latest values necessary. Redefining the function in the reactive statement is just a waste of CPU cycles.
+
+
+
+
+
+```svelte
+
+```
+
+
+
+## :wrench: Options
+
+Nothing
+
+## :heart: Compatibility
+
+This rule was taken from [@tivac/eslint-plugin-svelte].
+This rule is compatible with `@tivac/svelte/reactive-functions` rule.
+
+[@tivac/eslint-plugin-svelte]: https://github.com/tivac/eslint-plugin-svelte/
+## :mag: Implementation
+
+- [Rule source](https://github.com/ota-meshi/eslint-plugin-svelte/blob/main/src/rules/no-reactive-functions.ts)
+- [Test source](https://github.com/ota-meshi/eslint-plugin-svelte/blob/main/tests/src/rules/no-reactive-functions.ts)
diff --git a/src/rules/no-reactive-functions.ts b/src/rules/no-reactive-functions.ts
new file mode 100644
index 000000000..4b8c77951
--- /dev/null
+++ b/src/rules/no-reactive-functions.ts
@@ -0,0 +1,66 @@
+import type { TSESTree } from "@typescript-eslint/types"
+import type { AST } from "svelte-eslint-parser"
+import { createRule } from "../utils"
+
+export default createRule("no-reactive-functions", {
+ meta: {
+ docs: {
+ description:
+ "It's not necessary to define functions in reactive statements",
+ category: "Best Practices",
+ recommended: false,
+ },
+ hasSuggestions: true,
+ schema: [],
+ messages: {
+ noReactiveFns: `Do not create functions inside reactive statements unless absolutely necessary.`,
+ fixReactiveFns: `Move the function out of the reactive statement`,
+ },
+ type: "suggestion", // "problem", or "layout",
+ },
+ create(context) {
+ return {
+ // $: foo = () => { ... }
+ [`SvelteReactiveStatement > ExpressionStatement > AssignmentExpression > :function`](
+ node: TSESTree.ArrowFunctionExpression,
+ ) {
+ // Move upwards to include the entire label
+ const parent = node.parent?.parent?.parent
+
+ if (!parent) {
+ return false
+ }
+
+ const source = context.getSourceCode()
+
+ return context.report({
+ node: parent,
+ loc: parent.loc,
+ messageId: "noReactiveFns",
+ suggest: [
+ {
+ messageId: "fixReactiveFns",
+ fix(fixer) {
+ const tokens = source.getFirstTokens(parent, {
+ includeComments: false,
+ count: 3,
+ })
+
+ const noExtraSpace = source.isSpaceBetweenTokens(
+ tokens[1] as AST.Token,
+ tokens[2] as AST.Token,
+ )
+
+ // Replace the entire reactive label with "const"
+ return fixer.replaceTextRange(
+ [tokens[0].range[0], tokens[1].range[1]],
+ noExtraSpace ? "const" : "const ",
+ )
+ },
+ },
+ ],
+ })
+ },
+ }
+ },
+})
diff --git a/src/utils/rules.ts b/src/utils/rules.ts
index 4874d321f..791b05025 100644
--- a/src/utils/rules.ts
+++ b/src/utils/rules.ts
@@ -16,6 +16,7 @@ import noExtraReactiveCurlies from "../rules/no-extra-reactive-curlies"
import noInnerDeclarations from "../rules/no-inner-declarations"
import noNotFunctionHandler from "../rules/no-not-function-handler"
import noObjectInTextMustaches from "../rules/no-object-in-text-mustaches"
+import noReactiveFunctions from "../rules/no-reactive-functions"
import noReactiveLiterals from "../rules/no-reactive-literals"
import noShorthandStylePropertyOverrides from "../rules/no-shorthand-style-property-overrides"
import noSpacesAroundEqualSignsInAttribute from "../rules/no-spaces-around-equal-signs-in-attribute"
@@ -51,6 +52,7 @@ export const rules = [
noInnerDeclarations,
noNotFunctionHandler,
noObjectInTextMustaches,
+ noReactiveFunctions,
noReactiveLiterals,
noShorthandStylePropertyOverrides,
noSpacesAroundEqualSignsInAttribute,
diff --git a/tests/fixtures/rules/no-reactive-functions/invalid/test01-errors.json b/tests/fixtures/rules/no-reactive-functions/invalid/test01-errors.json
new file mode 100644
index 000000000..924be5e56
--- /dev/null
+++ b/tests/fixtures/rules/no-reactive-functions/invalid/test01-errors.json
@@ -0,0 +1,38 @@
+[
+ {
+ "message": "Do not create functions inside reactive statements unless absolutely necessary.",
+ "line": 3,
+ "column": 5,
+ "suggestions": [
+ {
+ "desc": "Move the function out of the reactive statement",
+ "messageId": "fixReactiveFns",
+ "output": "\n\n"
+ }
+ ]
+ },
+ {
+ "message": "Do not create functions inside reactive statements unless absolutely necessary.",
+ "line": 4,
+ "column": 5,
+ "suggestions": [
+ {
+ "desc": "Move the function out of the reactive statement",
+ "messageId": "fixReactiveFns",
+ "output": "\n\n"
+ }
+ ]
+ },
+ {
+ "message": "Do not create functions inside reactive statements unless absolutely necessary.",
+ "line": 5,
+ "column": 5,
+ "suggestions": [
+ {
+ "desc": "Move the function out of the reactive statement",
+ "messageId": "fixReactiveFns",
+ "output": "\n\n"
+ }
+ ]
+ }
+]
diff --git a/tests/fixtures/rules/no-reactive-functions/invalid/test01-input.svelte b/tests/fixtures/rules/no-reactive-functions/invalid/test01-input.svelte
new file mode 100644
index 000000000..b08cd8648
--- /dev/null
+++ b/tests/fixtures/rules/no-reactive-functions/invalid/test01-input.svelte
@@ -0,0 +1,6 @@
+
+
diff --git a/tests/fixtures/rules/no-reactive-functions/valid/test01-input.svelte b/tests/fixtures/rules/no-reactive-functions/valid/test01-input.svelte
new file mode 100644
index 000000000..1088d2b02
--- /dev/null
+++ b/tests/fixtures/rules/no-reactive-functions/valid/test01-input.svelte
@@ -0,0 +1,5 @@
+
+
diff --git a/tests/src/rules/no-reactive-functions.ts b/tests/src/rules/no-reactive-functions.ts
new file mode 100644
index 000000000..20033743d
--- /dev/null
+++ b/tests/src/rules/no-reactive-functions.ts
@@ -0,0 +1,16 @@
+import { RuleTester } from "eslint"
+import rule from "../../../src/rules/no-reactive-functions"
+import { loadTestCases } from "../../utils/utils"
+
+const tester = new RuleTester({
+ parserOptions: {
+ ecmaVersion: 2020,
+ sourceType: "module",
+ },
+})
+
+tester.run(
+ "no-reactive-functions",
+ rule as any,
+ loadTestCases("no-reactive-functions"),
+)