diff --git a/.changeset/serious-mayflies-yell.md b/.changeset/serious-mayflies-yell.md
new file mode 100644
index 000000000..a03e61934
--- /dev/null
+++ b/.changeset/serious-mayflies-yell.md
@@ -0,0 +1,5 @@
+---
+"eslint-plugin-svelte": minor
+---
+
+feat: Add `svelte/valid-context-access` rule
diff --git a/README.md b/README.md
index a5661af1c..17599fee5 100644
--- a/README.md
+++ b/README.md
@@ -320,6 +320,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. | :wrench: |
 | [svelte/valid-compile](https://sveltejs.github.io/eslint-plugin-svelte/rules/valid-compile/) | disallow warnings when compiling. | :star: |
+| [svelte/valid-context-access](https://sveltejs.github.io/eslint-plugin-svelte/rules/valid-context-access/) | context functions must be called during component initialization. |  |
 | [svelte/valid-prop-names-in-kit-pages](https://sveltejs.github.io/eslint-plugin-svelte/rules/valid-prop-names-in-kit-pages/) | disallow props other than data or errors in SvelteKit page components. |  |
 
 ## Security Vulnerability
diff --git a/docs/rules.md b/docs/rules.md
index ef85cb467..968875980 100644
--- a/docs/rules.md
+++ b/docs/rules.md
@@ -33,6 +33,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.                                               | :wrench:       |
 | [svelte/valid-compile](./rules/valid-compile.md)                                                               | disallow warnings when compiling.                                                                                                      | :star:         |
+| [svelte/valid-context-access](./rules/valid-context-access.md)                                                 | context functions must be called during component initialization.                                                                      |                |
 | [svelte/valid-prop-names-in-kit-pages](./rules/valid-prop-names-in-kit-pages.md)                               | disallow props other than data or errors in SvelteKit page components.                                                                 |                |
 
 ## Security Vulnerability
diff --git a/docs/rules/valid-context-access.md b/docs/rules/valid-context-access.md
new file mode 100644
index 000000000..365b4b23e
--- /dev/null
+++ b/docs/rules/valid-context-access.md
@@ -0,0 +1,79 @@
+---
+pageClass: "rule-details"
+sidebarDepth: 0
+title: "svelte/valid-context-access"
+description: "context functions must be called during component initialization."
+---
+
+# svelte/valid-context-access
+
+> context functions must be called during component initialization.
+
+- :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 where context API is called except during component initialization.
+
+<ESLintCodeBlock>
+
+<!--eslint-skip-->
+
+```svelte
+<script>
+  /* eslint svelte/valid-context-access: "error" */
+  import { setContext, onMount } from "svelte"
+
+  /** ✓ GOOD */
+  setContext("answer", 42)
+  ;(() => {
+    setContext("answer", 42)
+  })()
+
+  const init = () => {
+    setContext("answer", 42)
+  }
+
+  init()
+
+  /** ✗ BAD */
+  const update = () => {
+    setContext("answer", 42)
+  }
+
+  onMount(() => {
+    update()
+    setContext("answer", 42)
+  })
+
+  const update2 = async () => {
+    await Promise.resolve()
+    setContext("answer", 42)
+  }
+
+  ;(async () => {
+    await Promise.resolve()
+    setContext("answer", 42)
+  })()
+</script>
+```
+
+</ESLintCodeBlock>
+
+- :warning: This rule only inspects Svelte files, not JS / TS files.
+
+## :wrench: Options
+
+Nothing.
+
+## :books: Further Reading
+
+- [Svelte - Docs > RUN TIME > svelte > setContext](https://svelte.dev/docs#run-time-svelte-setcontext)
+- [Svelte - Docs > RUN TIME > svelte > getContext](https://svelte.dev/docs#run-time-svelte-getContext)
+- [Svelte - Docs > RUN TIME > svelte > hasContext](https://svelte.dev/docs#run-time-svelte-hasContext)
+- [Svelte - Docs > RUN TIME > svelte > getAllContexts](https://svelte.dev/docs#run-time-svelte-getAllContexts)
+
+## :mag: Implementation
+
+- [Rule source](https://github.com/sveltejs/eslint-plugin-svelte/blob/main/src/rules/valid-context-access.ts)
+- [Test source](https://github.com/sveltejs/eslint-plugin-svelte/blob/main/tests/src/rules/valid-context-access.ts)
diff --git a/src/rules/infinite-reactive-loop.ts b/src/rules/infinite-reactive-loop.ts
index 13ea8741a..fe0075e16 100644
--- a/src/rules/infinite-reactive-loop.ts
+++ b/src/rules/infinite-reactive-loop.ts
@@ -1,57 +1,11 @@
 import type { TSESTree } from "@typescript-eslint/types"
 import type { AST } from "svelte-eslint-parser"
-import { ReferenceTracker } from "@eslint-community/eslint-utils"
 import { createRule } from "../utils"
 import type { RuleContext } from "../types"
 import { findVariable } from "../utils/ast-utils"
 import { traverseNodes } from "svelte-eslint-parser"
-
-/**
- * Get usage of `tick`
- */
-function extractTickReferences(
-  context: RuleContext,
-): { node: TSESTree.CallExpression; name: string }[] {
-  const referenceTracker = new ReferenceTracker(
-    context.getSourceCode().scopeManager.globalScope!,
-  )
-  const a = referenceTracker.iterateEsmReferences({
-    svelte: {
-      [ReferenceTracker.ESM]: true,
-      tick: {
-        [ReferenceTracker.CALL]: true,
-      },
-    },
-  })
-  return Array.from(a).map(({ node, path }) => {
-    return {
-      node: node as TSESTree.CallExpression,
-      name: path[path.length - 1],
-    }
-  })
-}
-
-/**
- * Get usage of `setTimeout`, `setInterval`, `queueMicrotask`
- */
-function extractTaskReferences(
-  context: RuleContext,
-): { node: TSESTree.CallExpression; name: string }[] {
-  const referenceTracker = new ReferenceTracker(
-    context.getSourceCode().scopeManager.globalScope!,
-  )
-  const a = referenceTracker.iterateGlobalReferences({
-    setTimeout: { [ReferenceTracker.CALL]: true },
-    setInterval: { [ReferenceTracker.CALL]: true },
-    queueMicrotask: { [ReferenceTracker.CALL]: true },
-  })
-  return Array.from(a).map(({ node, path }) => {
-    return {
-      node: node as TSESTree.CallExpression,
-      name: path[path.length - 1],
-    }
-  })
-}
+import { extractSvelteLifeCycleReferences } from "./reference-helpers/svelte-lifecycle"
+import { extractTaskReferences } from "./reference-helpers/microtask"
 
 /**
  * If `node` is inside of `maybeAncestorNode`, return true.
@@ -400,12 +354,14 @@ export default createRule("infinite-reactive-loop", {
     type: "suggestion",
   },
   create(context) {
+    const tickCallExpressions = Array.from(
+      extractSvelteLifeCycleReferences(context, ["tick"]),
+    )
+    const taskReferences = Array.from(extractTaskReferences(context))
+    const reactiveVariableReferences = getReactiveVariableReferences(context)
+
     return {
       ["SvelteReactiveStatement"]: (ast: AST.SvelteReactiveStatement) => {
-        const tickCallExpressions = extractTickReferences(context)
-        const taskReferences = extractTaskReferences(context)
-        const reactiveVariableReferences =
-          getReactiveVariableReferences(context)
         const trackedVariableNodes = getTrackedVariableNodes(
           reactiveVariableReferences,
           ast,
diff --git a/src/rules/reference-helpers/microtask.ts b/src/rules/reference-helpers/microtask.ts
new file mode 100644
index 000000000..073b968a2
--- /dev/null
+++ b/src/rules/reference-helpers/microtask.ts
@@ -0,0 +1,37 @@
+import type { TSESTree } from "@typescript-eslint/types"
+import { ReferenceTracker } from "@eslint-community/eslint-utils"
+import type { RuleContext } from "../../types"
+
+type FunctionName = "setTimeout" | "setInterval" | "queueMicrotask"
+
+/**
+ * Get usage of `setTimeout`, `setInterval`, `queueMicrotask`
+ */
+export function* extractTaskReferences(
+  context: RuleContext,
+  functionNames: FunctionName[] = [
+    "setTimeout",
+    "setInterval",
+    "queueMicrotask",
+  ],
+): Generator<{ node: TSESTree.CallExpression; name: string }, void> {
+  const referenceTracker = new ReferenceTracker(
+    context.getSourceCode().scopeManager.globalScope!,
+  )
+  for (const { node, path } of referenceTracker.iterateGlobalReferences({
+    setTimeout: {
+      [ReferenceTracker.CALL]: functionNames.includes("setTimeout"),
+    },
+    setInterval: {
+      [ReferenceTracker.CALL]: functionNames.includes("setInterval"),
+    },
+    queueMicrotask: {
+      [ReferenceTracker.CALL]: functionNames.includes("queueMicrotask"),
+    },
+  })) {
+    yield {
+      node: node as TSESTree.CallExpression,
+      name: path[path.length - 1],
+    }
+  }
+}
diff --git a/src/rules/reference-helpers/svelte-context.ts b/src/rules/reference-helpers/svelte-context.ts
new file mode 100644
index 000000000..ebeb8f57a
--- /dev/null
+++ b/src/rules/reference-helpers/svelte-context.ts
@@ -0,0 +1,42 @@
+import type { TSESTree } from "@typescript-eslint/types"
+import { ReferenceTracker } from "@eslint-community/eslint-utils"
+import type { RuleContext } from "../../types"
+
+type ContextName = "setContext" | "getContext" | "hasContext" | "getAllContexts"
+
+/** Extract svelte's context API references */
+export function* extractContextReferences(
+  context: RuleContext,
+  contextNames: ContextName[] = [
+    "setContext",
+    "getContext",
+    "hasContext",
+    "getAllContexts",
+  ],
+): Generator<{ node: TSESTree.CallExpression; name: string }, void> {
+  const referenceTracker = new ReferenceTracker(
+    context.getSourceCode().scopeManager.globalScope!,
+  )
+  for (const { node, path } of referenceTracker.iterateEsmReferences({
+    svelte: {
+      [ReferenceTracker.ESM]: true,
+      setContext: {
+        [ReferenceTracker.CALL]: contextNames.includes("setContext"),
+      },
+      getContext: {
+        [ReferenceTracker.CALL]: contextNames.includes("getContext"),
+      },
+      hasContext: {
+        [ReferenceTracker.CALL]: contextNames.includes("hasContext"),
+      },
+      getAllContexts: {
+        [ReferenceTracker.CALL]: contextNames.includes("getAllContexts"),
+      },
+    },
+  })) {
+    yield {
+      node: node as TSESTree.CallExpression,
+      name: path[path.length - 1],
+    }
+  }
+}
diff --git a/src/rules/reference-helpers/svelte-lifecycle.ts b/src/rules/reference-helpers/svelte-lifecycle.ts
new file mode 100644
index 000000000..2b05069b7
--- /dev/null
+++ b/src/rules/reference-helpers/svelte-lifecycle.ts
@@ -0,0 +1,53 @@
+import type { TSESTree } from "@typescript-eslint/types"
+import { ReferenceTracker } from "@eslint-community/eslint-utils"
+import type { RuleContext } from "../../types"
+
+type LifeCycleName =
+  | "onMount"
+  | "beforeUpdate"
+  | "afterUpdate"
+  | "onDestroy"
+  | "tick"
+
+/**
+ * Get usage of Svelte life cycle functions.
+ */
+export function* extractSvelteLifeCycleReferences(
+  context: RuleContext,
+  fuctionName: LifeCycleName[] = [
+    "onMount",
+    "beforeUpdate",
+    "afterUpdate",
+    "onDestroy",
+    "tick",
+  ],
+): Generator<{ node: TSESTree.CallExpression; name: string }, void> {
+  const referenceTracker = new ReferenceTracker(
+    context.getSourceCode().scopeManager.globalScope!,
+  )
+  for (const { node, path } of referenceTracker.iterateEsmReferences({
+    svelte: {
+      [ReferenceTracker.ESM]: true,
+      onMount: {
+        [ReferenceTracker.CALL]: fuctionName.includes("onMount"),
+      },
+      beforeUpdate: {
+        [ReferenceTracker.CALL]: fuctionName.includes("beforeUpdate"),
+      },
+      afterUpdate: {
+        [ReferenceTracker.CALL]: fuctionName.includes("afterUpdate"),
+      },
+      onDestroy: {
+        [ReferenceTracker.CALL]: fuctionName.includes("onDestroy"),
+      },
+      tick: {
+        [ReferenceTracker.CALL]: fuctionName.includes("tick"),
+      },
+    },
+  })) {
+    yield {
+      node: node as TSESTree.CallExpression,
+      name: path[path.length - 1],
+    }
+  }
+}
diff --git a/src/rules/valid-context-access.ts b/src/rules/valid-context-access.ts
new file mode 100644
index 000000000..cd8490f1e
--- /dev/null
+++ b/src/rules/valid-context-access.ts
@@ -0,0 +1,223 @@
+import { createRule } from "../utils"
+import { extractContextReferences } from "./reference-helpers/svelte-context"
+import { extractSvelteLifeCycleReferences } from "./reference-helpers/svelte-lifecycle"
+import { extractTaskReferences } from "./reference-helpers/microtask"
+import { isInsideOfPromiseThenOrCatch } from "../utils/promise"
+import type { AST } from "svelte-eslint-parser"
+import type { TSESTree } from "@typescript-eslint/types"
+
+export default createRule("valid-context-access", {
+  meta: {
+    docs: {
+      description:
+        "context functions must be called during component initialization.",
+      category: "Possible Errors",
+      recommended: false,
+    },
+    schema: [],
+    messages: {
+      unexpected:
+        "Do not call {{function}} except during component initialization.",
+    },
+    type: "problem",
+  },
+  create(context) {
+    // // This rule doesn't check other than Svelte files.
+    if (!context.parserServices.isSvelte) {
+      return {}
+    }
+
+    const sourceCode = context.getSourceCode()
+    const lifeCycleReferences = Array.from(
+      extractSvelteLifeCycleReferences(context),
+    ).map((r) => r.node)
+    const taskReferences = Array.from(extractTaskReferences(context))
+
+    // Extract <script> blocks that is not module=context.
+    const scriptNotModuleElements: AST.SvelteScriptElement[] =
+      sourceCode.ast.body.filter((b) => {
+        if (b.type !== "SvelteScriptElement") return false
+        const isModule = b.startTag.attributes.some((a) => {
+          return (
+            a.type === "SvelteAttribute" &&
+            a.key.name === "context" &&
+            a.value.some(
+              (v) => v.type === "SvelteLiteral" && v.value === "module",
+            )
+          )
+        })
+        return !isModule
+      }) as AST.SvelteScriptElement[]
+
+    const scopeManager = sourceCode.scopeManager
+    const toplevelScope =
+      scopeManager.globalScope?.childScopes.find(
+        (scope) => scope.type === "module",
+      ) || scopeManager.globalScope
+
+    /** report ESLint error */
+    function report(node: TSESTree.CallExpression) {
+      context.report({
+        loc: node.loc,
+        messageId: "unexpected",
+        data: {
+          function:
+            node.callee.type === "Identifier"
+              ? node.callee.name
+              : "context function",
+        },
+      })
+    }
+
+    /** Get nodes where the variable is used */
+    function getReferences(id: TSESTree.Identifier | TSESTree.BindingName) {
+      const variable = toplevelScope?.variables.find((v) => {
+        if (id.type === "Identifier") {
+          return v.identifiers.includes(id)
+        }
+        return false
+      })
+      if (variable) {
+        return variable.references.filter((r) => r.identifier !== id)
+      }
+      return []
+    }
+
+    /** Return true if tnodeB is inside of nodeA. */
+    function isInsideOf(
+      nodeA: TSESTree.Node | AST.SvelteScriptElement,
+      nodeB: TSESTree.Node,
+    ) {
+      return (
+        nodeA.range[0] <= nodeB.range[0] && nodeB.range[1] <= nodeA.range[1]
+      )
+    }
+
+    /** Return true if the node is there inside of <script> block that is not module=context. */
+    function isInsideOfSvelteScriptElement(node: TSESTree.Node) {
+      for (const script of scriptNotModuleElements) {
+        if (isInsideOf(script, node)) {
+          return true
+        }
+      }
+      return false
+    }
+
+    const awaitExpressions: {
+      belongingFunction:
+        | TSESTree.FunctionDeclaration
+        | TSESTree.VariableDeclaration
+        | TSESTree.ArrowFunctionExpression
+      node: TSESTree.Node
+    }[] = []
+
+    /** Return true if the given node is later than the await expression. */
+    function isAfterAwait(node: TSESTree.CallExpression) {
+      for (const awaitExpression of awaitExpressions) {
+        const { belongingFunction, node: awaitNode } = awaitExpression
+        if (isInsideOf(node, belongingFunction)) {
+          continue
+        }
+        return awaitNode.range[0] <= node.range[0]
+      }
+      return false
+    }
+
+    /** Return true if node is inside of task function */
+    function isInsideTaskReference(node: TSESTree.CallExpression) {
+      for (const taskReference of taskReferences) {
+        if (isInsideOf(taskReference.node, node)) {
+          return true
+        }
+      }
+      return false
+    }
+
+    /** Let's lint! */
+    function doLint(
+      visitedCallExpressions: TSESTree.CallExpression[],
+      contextCallExpression: TSESTree.CallExpression,
+      currentNode: TSESTree.CallExpression,
+    ) {
+      // Report if context function is called outside of <script> block.
+      if (!isInsideOfSvelteScriptElement(currentNode)) {
+        report(contextCallExpression)
+        return
+      }
+
+      if (isAfterAwait(currentNode)) {
+        report(contextCallExpression)
+        return
+      }
+
+      if (isInsideTaskReference(currentNode)) {
+        report(contextCallExpression)
+        return
+      }
+
+      if (isInsideOfPromiseThenOrCatch(currentNode)) {
+        report(contextCallExpression)
+        return
+      }
+
+      let { parent } = currentNode
+      while (parent) {
+        parent = parent.parent
+        if (
+          parent?.type === "VariableDeclaration" ||
+          parent?.type === "FunctionDeclaration"
+        ) {
+          const references =
+            parent.type === "VariableDeclaration"
+              ? getReferences(parent.declarations[0].id)
+              : parent.id
+              ? getReferences(parent.id)
+              : []
+
+          for (const reference of references) {
+            if (reference.identifier?.parent?.type === "CallExpression") {
+              if (
+                !visitedCallExpressions.includes(reference.identifier.parent)
+              ) {
+                visitedCallExpressions.push(reference.identifier.parent)
+                doLint(
+                  visitedCallExpressions,
+                  contextCallExpression,
+                  reference.identifier?.parent,
+                )
+              }
+            }
+          }
+        } else if (parent?.type === "ExpressionStatement") {
+          if (parent.expression.type !== "CallExpression") {
+            report(contextCallExpression)
+          } else if (lifeCycleReferences.includes(parent.expression)) {
+            report(contextCallExpression)
+          }
+        }
+      }
+    }
+
+    return {
+      "Program:exit"() {
+        for (const { node } of extractContextReferences(context)) {
+          const visitedCallExpressions: TSESTree.CallExpression[] = []
+          doLint(visitedCallExpressions, node, node)
+        }
+      },
+      AwaitExpression(node) {
+        let parent: TSESTree.Node | undefined = node.parent
+        while (parent) {
+          if (
+            parent.type === "FunctionDeclaration" ||
+            parent.type === "VariableDeclaration" ||
+            parent.type === "ArrowFunctionExpression"
+          ) {
+            awaitExpressions.push({ belongingFunction: parent, node })
+          }
+          parent = parent.parent
+        }
+      },
+    }
+  },
+})
diff --git a/src/utils/promise.ts b/src/utils/promise.ts
new file mode 100644
index 000000000..0e97e1ee9
--- /dev/null
+++ b/src/utils/promise.ts
@@ -0,0 +1,31 @@
+import type { TSESTree } from "@typescript-eslint/types"
+
+/**
+ * Return true if `node` is inside of `then` or `catch`.
+ */
+export function isInsideOfPromiseThenOrCatch(node: TSESTree.Node): boolean {
+  let parent: TSESTree.Node | undefined = node.parent
+  while (parent) {
+    parent = parent.parent
+    if (parent?.type !== "ExpressionStatement") {
+      continue
+    }
+    const expression = parent?.expression
+    if (expression == null || expression?.type !== "CallExpression") {
+      return false
+    }
+
+    const callee = expression.callee
+    if (callee.type !== "MemberExpression") {
+      return false
+    }
+
+    const property = callee.property
+    return (
+      property.type === "Identifier" &&
+      ["then", "catch"].includes(property.name)
+    )
+  }
+
+  return false
+}
diff --git a/src/utils/rules.ts b/src/utils/rules.ts
index 7dac11750..487616784 100644
--- a/src/utils/rules.ts
+++ b/src/utils/rules.ts
@@ -57,6 +57,7 @@ import sortAttributes from "../rules/sort-attributes"
 import spacedHtmlComment from "../rules/spaced-html-comment"
 import system from "../rules/system"
 import validCompile from "../rules/valid-compile"
+import validContextAccess from "../rules/valid-context-access"
 import validEachKey from "../rules/valid-each-key"
 import validPropNamesInKitPages from "../rules/valid-prop-names-in-kit-pages"
 
@@ -116,6 +117,7 @@ export const rules = [
   spacedHtmlComment,
   system,
   validCompile,
+  validContextAccess,
   validEachKey,
   validPropNamesInKitPages,
 ] as RuleModule[]
diff --git a/tests/fixtures/rules/valid-context-access/invalid/case01-errors.yaml b/tests/fixtures/rules/valid-context-access/invalid/case01-errors.yaml
new file mode 100644
index 000000000..22f67eb10
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/invalid/case01-errors.yaml
@@ -0,0 +1,36 @@
+- message: Do not call setContext except during component initialization.
+  line: 11
+  column: 5
+- message: Do not call getContext except during component initialization.
+  line: 12
+  column: 5
+- message: Do not call hasContext except during component initialization.
+  line: 13
+  column: 5
+- message: Do not call getAllContexts except during component initialization.
+  line: 14
+  column: 5
+- message: Do not call setContext except during component initialization.
+  line: 18
+  column: 5
+- message: Do not call getContext except during component initialization.
+  line: 19
+  column: 5
+- message: Do not call hasContext except during component initialization.
+  line: 20
+  column: 5
+- message: Do not call getAllContexts except during component initialization.
+  line: 21
+  column: 5
+- message: Do not call setContext except during component initialization.
+  line: 25
+  column: 5
+- message: Do not call getContext except during component initialization.
+  line: 26
+  column: 5
+- message: Do not call hasContext except during component initialization.
+  line: 27
+  column: 5
+- message: Do not call getAllContexts except during component initialization.
+  line: 28
+  column: 5
diff --git a/tests/fixtures/rules/valid-context-access/invalid/case01-input.svelte b/tests/fixtures/rules/valid-context-access/invalid/case01-input.svelte
new file mode 100644
index 000000000..859baf1bb
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/invalid/case01-input.svelte
@@ -0,0 +1,36 @@
+<script>
+  import {
+    setContext,
+    getContext,
+    hasContext,
+    getAllContexts,
+    onMount,
+  } from "svelte"
+
+  const update1 = () => {
+    setContext("answer", 42)
+    getContext("answer")
+    hasContext("answer")
+    getAllContexts()
+  }
+
+  const update2 = function () {
+    setContext("answer", 42)
+    getContext("answer")
+    hasContext("answer")
+    getAllContexts()
+  }
+
+  function update3() {
+    setContext("answer", 42)
+    getContext("answer")
+    hasContext("answer")
+    getAllContexts()
+  }
+
+  onMount(() => {
+    update1()
+    update2()
+    update3()
+  })
+</script>
diff --git a/tests/fixtures/rules/valid-context-access/invalid/case02-errors.yaml b/tests/fixtures/rules/valid-context-access/invalid/case02-errors.yaml
new file mode 100644
index 000000000..f33732b66
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/invalid/case02-errors.yaml
@@ -0,0 +1,3 @@
+- message: Do not call setContext except during component initialization.
+  line: 5
+  column: 5
diff --git a/tests/fixtures/rules/valid-context-access/invalid/case02-input.svelte b/tests/fixtures/rules/valid-context-access/invalid/case02-input.svelte
new file mode 100644
index 000000000..b0af74395
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/invalid/case02-input.svelte
@@ -0,0 +1,7 @@
+<script>
+  import { setContext, onMount } from "svelte"
+
+  onMount(() => {
+    setContext("answer", 42)
+  })
+</script>
diff --git a/tests/fixtures/rules/valid-context-access/invalid/case03-errors.yaml b/tests/fixtures/rules/valid-context-access/invalid/case03-errors.yaml
new file mode 100644
index 000000000..96c6f1b93
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/invalid/case03-errors.yaml
@@ -0,0 +1,4 @@
+- message: Do not call setContext except during component initialization.
+  line: 4
+  column: 5
+  suggestions: null
diff --git a/tests/fixtures/rules/valid-context-access/invalid/case03-input.svelte b/tests/fixtures/rules/valid-context-access/invalid/case03-input.svelte
new file mode 100644
index 000000000..2df88bc18
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/invalid/case03-input.svelte
@@ -0,0 +1,8 @@
+<script>
+  import { setContext, onMount } from "svelte"
+  const something = () => {
+    setContext("answer", 42)
+  }
+</script>
+
+<button on:click={() => something()}>Click Me</button>
diff --git a/tests/fixtures/rules/valid-context-access/invalid/case04-errors.yaml b/tests/fixtures/rules/valid-context-access/invalid/case04-errors.yaml
new file mode 100644
index 000000000..96c6f1b93
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/invalid/case04-errors.yaml
@@ -0,0 +1,4 @@
+- message: Do not call setContext except during component initialization.
+  line: 4
+  column: 5
+  suggestions: null
diff --git a/tests/fixtures/rules/valid-context-access/invalid/case04-input.svelte b/tests/fixtures/rules/valid-context-access/invalid/case04-input.svelte
new file mode 100644
index 000000000..4b62a8d4e
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/invalid/case04-input.svelte
@@ -0,0 +1,13 @@
+<script>
+  import { setContext, onMount } from "svelte"
+  const something = () => {
+    setContext("answer", 42)
+  }
+
+  something()
+</script>
+
+{#if true}
+  {@const foo = something()}
+  <button>Click Me</button>
+{/if}
diff --git a/tests/fixtures/rules/valid-context-access/invalid/case05-errors.yaml b/tests/fixtures/rules/valid-context-access/invalid/case05-errors.yaml
new file mode 100644
index 000000000..96c6f1b93
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/invalid/case05-errors.yaml
@@ -0,0 +1,4 @@
+- message: Do not call setContext except during component initialization.
+  line: 4
+  column: 5
+  suggestions: null
diff --git a/tests/fixtures/rules/valid-context-access/invalid/case05-input.svelte b/tests/fixtures/rules/valid-context-access/invalid/case05-input.svelte
new file mode 100644
index 000000000..b21f3b9b8
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/invalid/case05-input.svelte
@@ -0,0 +1,12 @@
+<script>
+  import { setContext, onMount } from "svelte"
+  const something = () => {
+    setContext("answer", 42)
+  }
+
+  something()
+</script>
+
+{#if something()}
+  <button>Click Me</button>
+{/if}
diff --git a/tests/fixtures/rules/valid-context-access/invalid/case06-errors.yaml b/tests/fixtures/rules/valid-context-access/invalid/case06-errors.yaml
new file mode 100644
index 000000000..9d0ec949e
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/invalid/case06-errors.yaml
@@ -0,0 +1,4 @@
+- message: Do not call setContext except during component initialization.
+  line: 5
+  column: 7
+  suggestions: null
diff --git a/tests/fixtures/rules/valid-context-access/invalid/case06-input.svelte b/tests/fixtures/rules/valid-context-access/invalid/case06-input.svelte
new file mode 100644
index 000000000..310840bb8
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/invalid/case06-input.svelte
@@ -0,0 +1,15 @@
+<script>
+  import { setContext, onMount } from "svelte"
+  const something = () => {
+    const inner = () => {
+      setContext("answer", 42)
+    }
+    inner()
+  }
+
+  something()
+</script>
+
+{#if something()}
+  <button>Click Me</button>
+{/if}
diff --git a/tests/fixtures/rules/valid-context-access/invalid/case07-errors.yaml b/tests/fixtures/rules/valid-context-access/invalid/case07-errors.yaml
new file mode 100644
index 000000000..5702a7bed
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/invalid/case07-errors.yaml
@@ -0,0 +1,3 @@
+- message: Do not call hasContext except during component initialization.
+  line: 5
+  column: 9
diff --git a/tests/fixtures/rules/valid-context-access/invalid/case07-input.svelte b/tests/fixtures/rules/valid-context-access/invalid/case07-input.svelte
new file mode 100644
index 000000000..5484f2dc9
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/invalid/case07-input.svelte
@@ -0,0 +1,9 @@
+<script>
+  import { hasContext, onMount } from "svelte"
+
+  onMount(() => {
+    if (hasContext("answer")) {
+      console.log("The answer exist")
+    }
+  })
+</script>
diff --git a/tests/fixtures/rules/valid-context-access/invalid/case08-errors.yaml b/tests/fixtures/rules/valid-context-access/invalid/case08-errors.yaml
new file mode 100644
index 000000000..6e01eaa01
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/invalid/case08-errors.yaml
@@ -0,0 +1,3 @@
+- message: Do not call setContext except during component initialization.
+  line: 6
+  column: 5
diff --git a/tests/fixtures/rules/valid-context-access/invalid/case08-input.svelte b/tests/fixtures/rules/valid-context-access/invalid/case08-input.svelte
new file mode 100644
index 000000000..574c3b3ab
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/invalid/case08-input.svelte
@@ -0,0 +1,9 @@
+<script>
+  import { setContext } from "svelte"
+
+  const something = async () => {
+    await Promise.resolve()
+    setContext("answer", 42)
+  }
+  something()
+</script>
diff --git a/tests/fixtures/rules/valid-context-access/invalid/case09-errors.yaml b/tests/fixtures/rules/valid-context-access/invalid/case09-errors.yaml
new file mode 100644
index 000000000..8a807194f
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/invalid/case09-errors.yaml
@@ -0,0 +1,3 @@
+- message: Do not call setContext except during component initialization.
+  line: 3
+  column: 3
diff --git a/tests/fixtures/rules/valid-context-access/invalid/case09-input.svelte b/tests/fixtures/rules/valid-context-access/invalid/case09-input.svelte
new file mode 100644
index 000000000..0017cf865
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/invalid/case09-input.svelte
@@ -0,0 +1,4 @@
+<script context="module">
+  import { setContext } from "svelte"
+  setContext("answer", 42)
+</script>
diff --git a/tests/fixtures/rules/valid-context-access/invalid/case10-errors.yaml b/tests/fixtures/rules/valid-context-access/invalid/case10-errors.yaml
new file mode 100644
index 000000000..f33732b66
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/invalid/case10-errors.yaml
@@ -0,0 +1,3 @@
+- message: Do not call setContext except during component initialization.
+  line: 5
+  column: 5
diff --git a/tests/fixtures/rules/valid-context-access/invalid/case10-input.svelte b/tests/fixtures/rules/valid-context-access/invalid/case10-input.svelte
new file mode 100644
index 000000000..0d504f5ff
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/invalid/case10-input.svelte
@@ -0,0 +1,7 @@
+<script>
+  import { setContext } from "svelte"
+
+  setTimeout(() => {
+    setContext("answer", 42)
+  })
+</script>
diff --git a/tests/fixtures/rules/valid-context-access/invalid/case11-errors.yaml b/tests/fixtures/rules/valid-context-access/invalid/case11-errors.yaml
new file mode 100644
index 000000000..0897a75a9
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/invalid/case11-errors.yaml
@@ -0,0 +1,3 @@
+- message: Do not call setContext except during component initialization.
+  line: 6
+  column: 7
diff --git a/tests/fixtures/rules/valid-context-access/invalid/case11-input.svelte b/tests/fixtures/rules/valid-context-access/invalid/case11-input.svelte
new file mode 100644
index 000000000..dc9f3571b
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/invalid/case11-input.svelte
@@ -0,0 +1,11 @@
+<script>
+  import { setContext } from "svelte"
+
+  const doSomething = () => {
+    setTimeout(() => {
+      setContext("answer", 42)
+    })
+  }
+
+  doSomething()
+</script>
diff --git a/tests/fixtures/rules/valid-context-access/invalid/case12-errors.yaml b/tests/fixtures/rules/valid-context-access/invalid/case12-errors.yaml
new file mode 100644
index 000000000..28b8f23b8
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/invalid/case12-errors.yaml
@@ -0,0 +1,12 @@
+- message: Do not call setContext except during component initialization.
+  line: 5
+  column: 5
+- message: Do not call setContext except during component initialization.
+  line: 9
+  column: 5
+- message: Do not call setContext except during component initialization.
+  line: 13
+  column: 5
+- message: Do not call setContext except during component initialization.
+  line: 17
+  column: 5
diff --git a/tests/fixtures/rules/valid-context-access/invalid/case12-input.svelte b/tests/fixtures/rules/valid-context-access/invalid/case12-input.svelte
new file mode 100644
index 000000000..c170ecc49
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/invalid/case12-input.svelte
@@ -0,0 +1,19 @@
+<script>
+  import { setContext } from "svelte"
+
+  Promise.resolve().then(() => {
+    setContext("answer", 42)
+  })
+
+  Promise.resolve().then(function () {
+    setContext("answer", 42)
+  })
+
+  Promise.resolve().catch(() => {
+    setContext("answer", 42)
+  })
+
+  Promise.resolve().catch(function () {
+    setContext("answer", 42)
+  })
+</script>
diff --git a/tests/fixtures/rules/valid-context-access/invalid/case13-errors.yaml b/tests/fixtures/rules/valid-context-access/invalid/case13-errors.yaml
new file mode 100644
index 000000000..f33732b66
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/invalid/case13-errors.yaml
@@ -0,0 +1,3 @@
+- message: Do not call setContext except during component initialization.
+  line: 5
+  column: 5
diff --git a/tests/fixtures/rules/valid-context-access/invalid/case13-input.svelte b/tests/fixtures/rules/valid-context-access/invalid/case13-input.svelte
new file mode 100644
index 000000000..80ddb16c4
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/invalid/case13-input.svelte
@@ -0,0 +1,7 @@
+<script>
+  import { setContext } from "svelte"
+  ;(async () => {
+    await Promise.resolve()
+    setContext("answer", 42)
+  })()
+</script>
diff --git a/tests/fixtures/rules/valid-context-access/invalid/case14-errors.yaml b/tests/fixtures/rules/valid-context-access/invalid/case14-errors.yaml
new file mode 100644
index 000000000..4055b4a9a
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/invalid/case14-errors.yaml
@@ -0,0 +1,3 @@
+- message: Do not call setContext except during component initialization.
+  line: 4
+  column: 5
diff --git a/tests/fixtures/rules/valid-context-access/invalid/case14-input.svelte b/tests/fixtures/rules/valid-context-access/invalid/case14-input.svelte
new file mode 100644
index 000000000..e8a9b151e
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/invalid/case14-input.svelte
@@ -0,0 +1,10 @@
+<script>
+  import { setContext, onMount } from "svelte"
+  const doSomething = () => {
+    setContext("answer", 42)
+  }
+
+  onMount(() => {
+    doSomething()
+  })
+</script>
diff --git a/tests/fixtures/rules/valid-context-access/invalid/case15-errors.yaml b/tests/fixtures/rules/valid-context-access/invalid/case15-errors.yaml
new file mode 100644
index 000000000..4055b4a9a
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/invalid/case15-errors.yaml
@@ -0,0 +1,3 @@
+- message: Do not call setContext except during component initialization.
+  line: 4
+  column: 5
diff --git a/tests/fixtures/rules/valid-context-access/invalid/case15-input.svelte b/tests/fixtures/rules/valid-context-access/invalid/case15-input.svelte
new file mode 100644
index 000000000..f0df9c344
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/invalid/case15-input.svelte
@@ -0,0 +1,11 @@
+<script>
+  import { setContext, onMount } from "svelte"
+  const doSomething = () => {
+    setContext("answer", 42)
+  }
+
+  ;(async () => {
+    await Promise.resolve()
+    doSomething()
+  })()
+</script>
diff --git a/tests/fixtures/rules/valid-context-access/valid/case01-input.svelte b/tests/fixtures/rules/valid-context-access/valid/case01-input.svelte
new file mode 100644
index 000000000..3ec7fa441
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/valid/case01-input.svelte
@@ -0,0 +1,8 @@
+<script>
+  import { setContext, getContext, hasContext, getAllContexts } from "svelte"
+
+  setContext("answer", 42)
+  getContext("answer")
+  hasContext("answer")
+  getAllContexts()
+</script>
diff --git a/tests/fixtures/rules/valid-context-access/valid/case02-input.svelte b/tests/fixtures/rules/valid-context-access/valid/case02-input.svelte
new file mode 100644
index 000000000..bab6b283a
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/valid/case02-input.svelte
@@ -0,0 +1,6 @@
+<script>
+  import { setContext, onMount } from "svelte"
+  ;(() => {
+    setContext("answer", 42)
+  })()
+</script>
diff --git a/tests/fixtures/rules/valid-context-access/valid/case03-input.svelte b/tests/fixtures/rules/valid-context-access/valid/case03-input.svelte
new file mode 100644
index 000000000..461a5f1f3
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/valid/case03-input.svelte
@@ -0,0 +1,8 @@
+<script>
+  import { setContext } from "svelte"
+  const something = () => {
+    setContext("answer", 42)
+  }
+
+  something()
+</script>
diff --git a/tests/fixtures/rules/valid-context-access/valid/case04-input.svelte b/tests/fixtures/rules/valid-context-access/valid/case04-input.svelte
new file mode 100644
index 000000000..852518424
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/valid/case04-input.svelte
@@ -0,0 +1,15 @@
+<script>
+  import { setContext, onMount } from "svelte"
+  const something = () => {
+    setContext("answer", 42)
+  }
+
+  const something2 = () => {
+    something()
+  }
+
+  ;(() => {
+    something()
+    something2()
+  })()
+</script>
diff --git a/tests/fixtures/rules/valid-context-access/valid/case05-input.svelte b/tests/fixtures/rules/valid-context-access/valid/case05-input.svelte
new file mode 100644
index 000000000..49cce3bc7
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/valid/case05-input.svelte
@@ -0,0 +1,6 @@
+<script>
+  import { setContext, onMount } from "svelte"
+  const something = () => {
+    setContext("answer", 42)
+  }
+</script>
diff --git a/tests/fixtures/rules/valid-context-access/valid/case06-input.svelte b/tests/fixtures/rules/valid-context-access/valid/case06-input.svelte
new file mode 100644
index 000000000..17e2ae7e2
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/valid/case06-input.svelte
@@ -0,0 +1,15 @@
+<script>
+  import { setContext, onMount } from "svelte"
+  const something = () => {
+    something2()
+    setContext("answer", 42)
+  }
+
+  const something2 = () => {
+    something()
+    setContext("answer", 42)
+  }
+
+  something()
+  something2()
+</script>
diff --git a/tests/fixtures/rules/valid-context-access/valid/case07-input.svelte b/tests/fixtures/rules/valid-context-access/valid/case07-input.svelte
new file mode 100644
index 000000000..24c5ae0a4
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/valid/case07-input.svelte
@@ -0,0 +1,12 @@
+<script>
+  import { setContext, onMount } from "svelte"
+  const something = () => {
+    setContext("answer", 42)
+  }
+
+  something()
+</script>
+
+{#if something}
+  <button>Click Me</button>
+{/if}
diff --git a/tests/fixtures/rules/valid-context-access/valid/case08-input.svelte b/tests/fixtures/rules/valid-context-access/valid/case08-input.svelte
new file mode 100644
index 000000000..c0b2b1d8b
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/valid/case08-input.svelte
@@ -0,0 +1,22 @@
+<script>
+  import { setContext, onMount } from "svelte"
+
+  if (setContext("answer", 42)) {
+    console.log("setContext")
+  } else if (setContext("answer", 43)) {
+    console.log("setContext")
+  }
+
+  switch (setContext("answer", 42)) {
+    case 1:
+      console.log("setContext")
+      break
+    case 2:
+      console.log("setContext")
+      break
+    default:
+      console.log("setContext")
+  }
+
+  const foo = setContext("answer", 42) ? "bar" : "baz"
+</script>
diff --git a/tests/fixtures/rules/valid-context-access/valid/case09-input.js b/tests/fixtures/rules/valid-context-access/valid/case09-input.js
new file mode 100644
index 000000000..4d3f8fe4c
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/valid/case09-input.js
@@ -0,0 +1,17 @@
+import { setContext } from "svelte"
+
+const something = () => {
+  setContext("answer", 42)
+}
+
+const something2 = async () => {
+  await Promise.resolve()
+  setContext("answer", 42)
+}
+
+const aaa = (fn) => {
+  fn()
+}
+
+aaa(() => something())
+something2()
diff --git a/tests/fixtures/rules/valid-context-access/valid/case10-input.svelte b/tests/fixtures/rules/valid-context-access/valid/case10-input.svelte
new file mode 100644
index 000000000..fac4aafc3
--- /dev/null
+++ b/tests/fixtures/rules/valid-context-access/valid/case10-input.svelte
@@ -0,0 +1,6 @@
+<script>
+  import { setContext, onMount } from "svelte"
+
+  const something = (fn) => fn()
+  something(() => setContext("answer", 42))
+</script>
diff --git a/tests/src/rules/valid-context-access.ts b/tests/src/rules/valid-context-access.ts
new file mode 100644
index 000000000..f40dafd6d
--- /dev/null
+++ b/tests/src/rules/valid-context-access.ts
@@ -0,0 +1,20 @@
+import { RuleTester } from "eslint"
+import rule from "../../../src/rules/valid-context-access"
+import { loadTestCases } from "../../utils/utils"
+
+const tester = new RuleTester({
+  parserOptions: {
+    ecmaVersion: 2020,
+    sourceType: "module",
+  },
+  env: {
+    browser: true,
+    es2017: true,
+  },
+})
+
+tester.run(
+  "valid-context-access",
+  rule as any,
+  loadTestCases("valid-context-access"),
+)