diff --git a/.claude/rules/use-memo-directive.md b/.claude/rules/use-memo-directive.md
new file mode 100644
index 0000000000..19f0817384
--- /dev/null
+++ b/.claude/rules/use-memo-directive.md
@@ -0,0 +1,43 @@
+---
+description: When writing or editing React components or custom hooks
+---
+
+# 'use memo' Directive Rule
+
+Always place `'use memo'` at the very top of the function body for **both React components and custom hooks** (`use*` functions).
+
+## Why
+
+This project uses the React Compiler in annotation mode (`babel-plugin-react-compiler`). The `'use memo'` directive opts the function in to full compiler optimization — automatic memoization of values, callbacks, and JSX without manual `useMemo`/`useCallback`. Omitting it from hooks means the hook's internals are not optimized, even if the components consuming it are.
+
+## Pattern
+
+```tsx
+// ✅ Component — always add 'use memo'
+function MyComponent({ id }: Props) {
+ 'use memo';
+
+ return
{id}
;
+}
+
+// ✅ Custom hook — always add 'use memo'
+const useMyData = (id: string) => {
+ 'use memo';
+
+ return useQuery(id);
+};
+
+// ❌ Missing in hook — not optimized
+const useMyData = (id: string) => {
+ return useQuery(id);
+};
+```
+
+## Rules
+
+1. Add `'use memo'` as the **first statement** in the function body — before any hooks, variables, or logic.
+2. Apply to **both components and custom hooks** (`use*` naming convention).
+3. Comments before the directive are allowed.
+4. Use single or double quotes — **not backticks**.
+5. **Never remove** an existing `'use memo'` directive.
+6. Do not add `'use memo'` inside helper functions that are not components or hooks (plain utilities, event handlers, etc.).
diff --git a/.github/instructions/react.instructions.md b/.github/instructions/react.instructions.md
index 22090247ee..69251ad507 100644
--- a/.github/instructions/react.instructions.md
+++ b/.github/instructions/react.instructions.md
@@ -8,10 +8,10 @@ These instructions apply to React components in the `/react` directory.
## React Compiler Optimization
-### 'use memo' Directive (Recommended)
+### 'use memo' Directive (Required)
- This project uses the new **React Compiler**.
-- We actively use React directives such as `use memo` and `use client` at the top components (NOT files).
+- We actively use React directives such as `use memo` and `use client` at the top of **component and custom hook** function bodies (NOT files).
- `use memo` is **intentional and valid** in this codebase.
- Even if tooling or TypeScript/ESLint shows something like:
- `Unknown directive: 'use memo'.`
@@ -20,8 +20,8 @@ These instructions apply to React components in the `/react` directory.
### What should do
-- When generating or editing React components:
- - Prefer adding `use memo` when it is beneficial for React Compiler.
+- When generating or editing React components **or custom hooks** (`use*` functions):
+ - **Always** add `'use memo'` at the top of the function body.
- **Never** remove existing `use memo` directives.
- **Never** “fix” or “rename” `use memo` to something else.
- **Never** add comments suggesting that `use memo` is unknown, invalid, or deprecated.
@@ -37,7 +37,7 @@ The `'use memo'` directive has **strict placement requirements**:
- Only the first directive is processed; additional directives are ignored
```typescript
-// ✅ Good: 'use memo' at the very beginning of function body
+// ✅ Good: 'use memo' at the very beginning of component body
function MyComponent({ data }: Props) {
'use memo';
@@ -46,6 +46,14 @@ function MyComponent({ data }: Props) {
return {data}
;
}
+// ✅ Good: 'use memo' in custom hooks too
+const useMyHook = (id: string) => {
+ 'use memo';
+
+ const [value, setValue] = useState(null);
+ return value;
+};
+
// ✅ Good: Comments before 'use memo' are OK
const AnotherComponent: React.FC = ({ data }) => {
// This component is optimized by React Compiler
@@ -74,6 +82,12 @@ function BacktickBad({ data }: Props) {
`use memo`; // ❌ Must use quotes, not backticks
return {data}
;
}
+
+// ❌ Bad: Missing 'use memo' in a new custom hook
+function useData(id: string) {
+ // ❌ Should have 'use memo' at the top
+ return useSomeQuery(id);
+}
```
### Manual Optimization Hooks (Use Sparingly)
@@ -1056,7 +1070,7 @@ When reviewing React code, check for:
### React Compiler & Optimization
-- [ ] Component uses `'use memo'` directive if it's a new component
+- [ ] Component and custom hook (`use*`) uses `'use memo'` directive if new
- [ ] No unnecessary `useMemo`/`useCallback` (prefer 'use memo' directive)
- [ ] `useEffectEvent` is used for non-reactive logic in Effects when appropriate