diff --git a/.changeset/ready-views-burn.md b/.changeset/ready-views-burn.md
new file mode 100644
index 000000000..a5f11d84b
--- /dev/null
+++ b/.changeset/ready-views-burn.md
@@ -0,0 +1,5 @@
+---
+'eslint-plugin-svelte': minor
+---
+
+feat: add `prefer-writable-derived` rule
diff --git a/README.md b/README.md
index c379a3d82..f9c7bfee2 100644
--- a/README.md
+++ b/README.md
@@ -310,6 +310,7 @@ These rules relate to better ways of doing things to help you avoid problems:
| [svelte/no-useless-mustaches](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-useless-mustaches/) | disallow unnecessary mustache interpolations | :star::wrench: |
| [svelte/prefer-const](https://sveltejs.github.io/eslint-plugin-svelte/rules/prefer-const/) | Require `const` declarations for variables that are never reassigned after declared | :wrench: |
| [svelte/prefer-destructured-store-props](https://sveltejs.github.io/eslint-plugin-svelte/rules/prefer-destructured-store-props/) | destructure values from object stores for better change tracking & fewer redraws | :bulb: |
+| [svelte/prefer-writable-derived](https://sveltejs.github.io/eslint-plugin-svelte/rules/prefer-writable-derived/) | Prefer using writable $derived instead of $state and $effect | :star::bulb: |
| [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 | |
diff --git a/docs/rules.md b/docs/rules.md
index df2ca5ec4..7433dee57 100644
--- a/docs/rules.md
+++ b/docs/rules.md
@@ -67,6 +67,7 @@ These rules relate to better ways of doing things to help you avoid problems:
| [svelte/no-useless-mustaches](./rules/no-useless-mustaches.md) | disallow unnecessary mustache interpolations | :star::wrench: |
| [svelte/prefer-const](./rules/prefer-const.md) | Require `const` declarations for variables that are never reassigned after declared | :wrench: |
| [svelte/prefer-destructured-store-props](./rules/prefer-destructured-store-props.md) | destructure values from object stores for better change tracking & fewer redraws | :bulb: |
+| [svelte/prefer-writable-derived](./rules/prefer-writable-derived.md) | Prefer using writable $derived instead of $state and $effect | :star::bulb: |
| [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 | |
diff --git a/docs/rules/prefer-writable-derived.md b/docs/rules/prefer-writable-derived.md
new file mode 100644
index 000000000..830bec2aa
--- /dev/null
+++ b/docs/rules/prefer-writable-derived.md
@@ -0,0 +1,60 @@
+---
+pageClass: 'rule-details'
+sidebarDepth: 0
+title: 'svelte/prefer-writable-derived'
+description: 'Prefer using writable $derived instead of $state and $effect'
+---
+
+# svelte/prefer-writable-derived
+
+> Prefer using writable $derived instead of $state and $effect
+
+- :exclamation: **_This rule has not been released yet._**
+- :gear: This rule is included in `"plugin:svelte/recommended"`.
+- :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 when you use a combination of `$state` and `$effect` to create a derived value that can be written to. It encourages using the more concise and clearer `$derived` syntax instead.
+
+
+
+```svelte
+
+```
+
+The rule specifically looks for patterns where:
+
+1. You initialize a variable with `$state()`
+2. You then use `$effect()` or `$effect.pre()` to assign a new value to that same variable
+3. The effect function contains only a single assignment statement
+
+When this pattern is detected, the rule suggests refactoring to use `$derived()` instead, which provides the same functionality in a more concise way.
+
+## :wrench: Options
+
+Nothing.
+
+- This rule has no options.
+
+## :books: Further Reading
+
+- [Svelte Documentation on Reactivity Primitives](https://svelte.dev/docs/svelte-components#script-2-assignments-are-reactive)
+- [Svelte RFC for Reactivity Primitives](https://github.com/sveltejs/rfcs/blob/rfc-better-primitives/text/0000-better-primitives.md)
+
+## :mag: Implementation
+
+- [Rule source](https://github.com/sveltejs/eslint-plugin-svelte/blob/main/packages/eslint-plugin-svelte/src/rules/prefer-writable-derived.ts)
+- [Test source](https://github.com/sveltejs/eslint-plugin-svelte/blob/main/packages/eslint-plugin-svelte/tests/src/rules/prefer-writable-derived.ts)
diff --git a/packages/eslint-plugin-svelte/src/configs/flat/recommended.ts b/packages/eslint-plugin-svelte/src/configs/flat/recommended.ts
index b1b2d51ad..7a08befc8 100644
--- a/packages/eslint-plugin-svelte/src/configs/flat/recommended.ts
+++ b/packages/eslint-plugin-svelte/src/configs/flat/recommended.ts
@@ -37,6 +37,7 @@ const config: Linter.Config[] = [
'svelte/no-unused-svelte-ignore': 'error',
'svelte/no-useless-children-snippet': 'error',
'svelte/no-useless-mustaches': 'error',
+ 'svelte/prefer-writable-derived': 'error',
'svelte/require-each-key': 'error',
'svelte/require-event-dispatcher-types': 'error',
'svelte/require-store-reactive-access': 'error',
diff --git a/packages/eslint-plugin-svelte/src/rule-types.ts b/packages/eslint-plugin-svelte/src/rule-types.ts
index 19e30a345..5da4f15a4 100644
--- a/packages/eslint-plugin-svelte/src/rule-types.ts
+++ b/packages/eslint-plugin-svelte/src/rule-types.ts
@@ -306,6 +306,11 @@ export interface RuleOptions {
* @see https://sveltejs.github.io/eslint-plugin-svelte/rules/prefer-style-directive/
*/
'svelte/prefer-style-directive'?: Linter.RuleEntry<[]>
+ /**
+ * Prefer using writable $derived instead of $state and $effect
+ * @see https://sveltejs.github.io/eslint-plugin-svelte/rules/prefer-writable-derived/
+ */
+ 'svelte/prefer-writable-derived'?: Linter.RuleEntry<[]>
/**
* require keyed `{#each}` block
* @see https://sveltejs.github.io/eslint-plugin-svelte/rules/require-each-key/
diff --git a/packages/eslint-plugin-svelte/src/rules/prefer-writable-derived.ts b/packages/eslint-plugin-svelte/src/rules/prefer-writable-derived.ts
new file mode 100644
index 000000000..c7f859dbd
--- /dev/null
+++ b/packages/eslint-plugin-svelte/src/rules/prefer-writable-derived.ts
@@ -0,0 +1,147 @@
+import type { TSESTree } from '@typescript-eslint/types';
+import { createRule } from '../utils/index.js';
+import { getScope } from '../utils/ast-utils.js';
+import { VERSION as SVELTE_VERSION } from 'svelte/compiler';
+import semver from 'semver';
+
+// Writable derived were introduced in Svelte 5.25.0
+const shouldRun = semver.satisfies(SVELTE_VERSION, '>=5.25.0');
+
+type ValidFunctionType = TSESTree.FunctionExpression | TSESTree.ArrowFunctionExpression;
+type ValidFunction = ValidFunctionType & {
+ body: TSESTree.BlockStatement;
+};
+
+type ValidAssignmentExpression = TSESTree.AssignmentExpression & {
+ operator: '=';
+ left: TSESTree.Identifier;
+};
+
+type ValidExpressionStatement = TSESTree.ExpressionStatement & {
+ expression: ValidAssignmentExpression;
+};
+
+function isEffectOrEffectPre(node: TSESTree.CallExpression) {
+ if (node.callee.type === 'Identifier') {
+ return node.callee.name === '$effect';
+ }
+ if (node.callee.type === 'MemberExpression') {
+ return (
+ node.callee.object.type === 'Identifier' &&
+ node.callee.object.name === '$effect' &&
+ node.callee.property.type === 'Identifier' &&
+ node.callee.property.name === 'pre'
+ );
+ }
+
+ return false;
+}
+
+function isValidFunctionArgument(argument: TSESTree.Node): argument is ValidFunction {
+ if (
+ (argument.type !== 'FunctionExpression' && argument.type !== 'ArrowFunctionExpression') ||
+ argument.params.length !== 0
+ ) {
+ return false;
+ }
+
+ if (argument.body.type !== 'BlockStatement') {
+ return false;
+ }
+
+ return argument.body.body.length === 1;
+}
+
+function isValidAssignment(statement: TSESTree.Statement): statement is ValidExpressionStatement {
+ if (statement.type !== 'ExpressionStatement') return false;
+
+ const { expression } = statement;
+ return (
+ expression.type === 'AssignmentExpression' &&
+ expression.operator === '=' &&
+ expression.left.type === 'Identifier'
+ );
+}
+
+function isStateVariable(init: TSESTree.Expression | null): init is TSESTree.CallExpression {
+ return (
+ init?.type === 'CallExpression' &&
+ init.callee.type === 'Identifier' &&
+ init.callee.name === '$state'
+ );
+}
+
+export default createRule('prefer-writable-derived', {
+ meta: {
+ docs: {
+ description: 'Prefer using writable $derived instead of $state and $effect',
+ category: 'Best Practices',
+ recommended: true
+ },
+ schema: [],
+ messages: {
+ unexpected: 'Prefer using writable $derived instead of $state and $effect',
+ suggestRewrite: 'Rewrite $state and $effect to $derived'
+ },
+ type: 'suggestion',
+ conditions: [
+ {
+ svelteVersions: ['5'],
+ runes: [true, 'undetermined']
+ }
+ ],
+ hasSuggestions: true
+ },
+ create(context) {
+ if (!shouldRun) {
+ return {};
+ }
+ return {
+ CallExpression: (node: TSESTree.CallExpression) => {
+ if (!isEffectOrEffectPre(node) || node.arguments.length !== 1) {
+ return;
+ }
+
+ const argument = node.arguments[0];
+ if (!isValidFunctionArgument(argument)) {
+ return;
+ }
+
+ const statement = argument.body.body[0];
+ if (!isValidAssignment(statement)) {
+ return;
+ }
+
+ const { left, right } = statement.expression;
+ const scope = getScope(context, statement);
+ const reference = scope.references.find(
+ (ref) => ref.identifier.type === 'Identifier' && ref.identifier.name === left.name
+ );
+
+ const def = reference?.resolved?.defs?.[0];
+ if (!def || def.type !== 'Variable' || def.node.type !== 'VariableDeclarator') {
+ return;
+ }
+
+ const { init } = def.node;
+ if (!isStateVariable(init)) {
+ return;
+ }
+
+ context.report({
+ node: def.node,
+ messageId: 'unexpected',
+ suggest: [
+ {
+ messageId: 'suggestRewrite',
+ fix: (fixer) => {
+ const rightCode = context.sourceCode.getText(right);
+ return [fixer.replaceText(init, `$derived(${rightCode})`), fixer.remove(node)];
+ }
+ }
+ ]
+ });
+ }
+ };
+ }
+});
diff --git a/packages/eslint-plugin-svelte/src/utils/rules.ts b/packages/eslint-plugin-svelte/src/utils/rules.ts
index 3151d17f1..baf9f45b4 100644
--- a/packages/eslint-plugin-svelte/src/utils/rules.ts
+++ b/packages/eslint-plugin-svelte/src/utils/rules.ts
@@ -60,6 +60,7 @@ import preferClassDirective from '../rules/prefer-class-directive.js';
import preferConst from '../rules/prefer-const.js';
import preferDestructuredStoreProps from '../rules/prefer-destructured-store-props.js';
import preferStyleDirective from '../rules/prefer-style-directive.js';
+import preferWritableDerived from '../rules/prefer-writable-derived.js';
import requireEachKey from '../rules/require-each-key.js';
import requireEventDispatcherTypes from '../rules/require-event-dispatcher-types.js';
import requireOptimizedStyleAttribute from '../rules/require-optimized-style-attribute.js';
@@ -135,6 +136,7 @@ export const rules = [
preferConst,
preferDestructuredStoreProps,
preferStyleDirective,
+ preferWritableDerived,
requireEachKey,
requireEventDispatcherTypes,
requireOptimizedStyleAttribute,
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/_requirements.json b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/_requirements.json
new file mode 100644
index 000000000..0192b1098
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/_requirements.json
@@ -0,0 +1,3 @@
+{
+ "svelte": ">=5.0.0-0"
+}
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/basic1-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/basic1-errors.yaml
new file mode 100644
index 000000000..600473adf
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/basic1-errors.yaml
@@ -0,0 +1,15 @@
+- message: Prefer using writable $derived instead of $state and $effect
+ line: 4
+ column: 6
+ suggestions:
+ - desc: Rewrite $state and $effect to $derived
+ messageId: suggestRewrite
+ output: |
+
+
+
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/basic1-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/basic1-input.svelte
new file mode 100644
index 000000000..51523f5c3
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/basic1-input.svelte
@@ -0,0 +1,10 @@
+
+
+
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/basic2-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/basic2-errors.yaml
new file mode 100644
index 000000000..b89390b86
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/basic2-errors.yaml
@@ -0,0 +1,15 @@
+- message: Prefer using writable $derived instead of $state and $effect
+ line: 4
+ column: 6
+ suggestions:
+ - desc: Rewrite $state and $effect to $derived
+ messageId: suggestRewrite
+ output: |
+
+
+
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/basic2-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/basic2-input.svelte
new file mode 100644
index 000000000..e8b6769c6
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/basic2-input.svelte
@@ -0,0 +1,10 @@
+
+
+
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/effect-pre1-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/effect-pre1-errors.yaml
new file mode 100644
index 000000000..600473adf
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/effect-pre1-errors.yaml
@@ -0,0 +1,15 @@
+- message: Prefer using writable $derived instead of $state and $effect
+ line: 4
+ column: 6
+ suggestions:
+ - desc: Rewrite $state and $effect to $derived
+ messageId: suggestRewrite
+ output: |
+
+
+
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/effect-pre1-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/effect-pre1-input.svelte
new file mode 100644
index 000000000..fdafad808
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/effect-pre1-input.svelte
@@ -0,0 +1,10 @@
+
+
+
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/effect-pre2-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/effect-pre2-errors.yaml
new file mode 100644
index 000000000..b89390b86
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/effect-pre2-errors.yaml
@@ -0,0 +1,15 @@
+- message: Prefer using writable $derived instead of $state and $effect
+ line: 4
+ column: 6
+ suggestions:
+ - desc: Rewrite $state and $effect to $derived
+ messageId: suggestRewrite
+ output: |
+
+
+
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/effect-pre2-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/effect-pre2-input.svelte
new file mode 100644
index 000000000..ee0e91b2b
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/effect-pre2-input.svelte
@@ -0,0 +1,10 @@
+
+
+
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/multiple-reassign1-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/multiple-reassign1-errors.yaml
new file mode 100644
index 000000000..f443ce89a
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/multiple-reassign1-errors.yaml
@@ -0,0 +1,19 @@
+- message: Prefer using writable $derived instead of $state and $effect
+ line: 4
+ column: 6
+ suggestions:
+ - desc: Rewrite $state and $effect to $derived
+ messageId: suggestRewrite
+ output: |
+
+
+
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/multiple-reassign1-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/multiple-reassign1-input.svelte
new file mode 100644
index 000000000..52fce48ad
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/multiple-reassign1-input.svelte
@@ -0,0 +1,14 @@
+
+
+
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/multiple-reassign2-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/multiple-reassign2-errors.yaml
new file mode 100644
index 000000000..d77136489
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/multiple-reassign2-errors.yaml
@@ -0,0 +1,19 @@
+- message: Prefer using writable $derived instead of $state and $effect
+ line: 4
+ column: 6
+ suggestions:
+ - desc: Rewrite $state and $effect to $derived
+ messageId: suggestRewrite
+ output: |
+
+
+ {
+ newAlbumName = value;
+ }}
+ />
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/multiple-reassign2-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/multiple-reassign2-input.svelte
new file mode 100644
index 000000000..9f42e657a
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/multiple-reassign2-input.svelte
@@ -0,0 +1,14 @@
+
+
+ {
+ newAlbumName = value;
+ }}
+/>
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/multiple-reassign3-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/multiple-reassign3-errors.yaml
new file mode 100644
index 000000000..0118d5e29
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/multiple-reassign3-errors.yaml
@@ -0,0 +1,38 @@
+- message: Prefer using writable $derived instead of $state and $effect
+ line: 4
+ column: 6
+ suggestions:
+ - desc: Rewrite $state and $effect to $derived
+ messageId: suggestRewrite
+ output: |
+
+
+
+- message: Prefer using writable $derived instead of $state and $effect
+ line: 4
+ column: 6
+ suggestions:
+ - desc: Rewrite $state and $effect to $derived
+ messageId: suggestRewrite
+ output: |
+
+
+
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/multiple-reassign3-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/multiple-reassign3-input.svelte
new file mode 100644
index 000000000..bb6169e60
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/invalid/multiple-reassign3-input.svelte
@@ -0,0 +1,14 @@
+
+
+
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/valid/_requirements.json b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/valid/_requirements.json
new file mode 100644
index 000000000..0192b1098
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/valid/_requirements.json
@@ -0,0 +1,3 @@
+{
+ "svelte": ">=5.0.0-0"
+}
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/valid/condition1-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/valid/condition1-input.svelte
new file mode 100644
index 000000000..57bd65848
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/valid/condition1-input.svelte
@@ -0,0 +1,13 @@
+
+
+
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/valid/condition2-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/valid/condition2-input.svelte
new file mode 100644
index 000000000..9083881f1
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-writable-derived/valid/condition2-input.svelte
@@ -0,0 +1,17 @@
+
+
+
diff --git a/packages/eslint-plugin-svelte/tests/src/rules/prefer-writable-derived.ts b/packages/eslint-plugin-svelte/tests/src/rules/prefer-writable-derived.ts
new file mode 100644
index 000000000..80e9065a7
--- /dev/null
+++ b/packages/eslint-plugin-svelte/tests/src/rules/prefer-writable-derived.ts
@@ -0,0 +1,12 @@
+import { RuleTester } from '../../utils/eslint-compat.js';
+import rule from '../../../src/rules/prefer-writable-derived.js';
+import { loadTestCases } from '../../utils/utils.js';
+
+const tester = new RuleTester({
+ languageOptions: {
+ ecmaVersion: 2020,
+ sourceType: 'module'
+ }
+});
+
+tester.run('prefer-writable-derived', rule as any, loadTestCases('prefer-writable-derived'));