# No Use Effect

Enforce the no-useEffect rule when writing or reviewing React code.

- Repository: https://github.com/humanlayer/humanlayer (12740 stars)
- Category: AI and agents
- License: Apache-2.0
- Last updated: 2026-10-31
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add humanlayer/humanlayer --skill no-use-effect -g -a claude-code -y`
Codex: `npx skills add humanlayer/humanlayer --skill no-use-effect -g -a codex -y`
Cursor: `npx skills add humanlayer/humanlayer --skill no-use-effect -g -a cursor -y`
Gemini CLI: `npx skills add humanlayer/humanlayer --skill no-use-effect -g -a gemini-cli -y`

## Description

Enforce the no-useEffect rule when writing or reviewing React code. ACTIVATE when writing React components, refactoring existing useEffect calls, reviewing PRs with useEffect, or when an agent adds useEffect "just in case." Provides the five replacement patterns and the useMountEffect escape hatch.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# No useEffect

Never call `useEffect` directly. Use derived state, event handlers, data-fetching libraries, or `useMountEffect` instead.

## Quick Reference
This skill is dervied from the  React docs: [You Might Not Need an Effect]($SKILLBASE/references/you-might-not-need-an-effect.md). IMPORTANT: when this skill is invoked you MUST read this post in entirety.

| Instead of useEffect for... | Use |
|----------------------------|-----|
| Deriving state from other state/props | Inline computation (Rule 1) |
| Fetching data | `useQuery` / data-fetching library (Rule 2) |
| Responding to user actions | Event handlers (Rule 3) |
| One-time external sync on mount | `useMountEffect` (Rule 4) |
| Resetting state when a prop changes | `key` prop on parent (Rule 5) |

## When to Use This Skill

- Writing new React components
- Refactoring existing `useEffect` calls
- Reviewing PRs that introduce `useEffect`
- An agent adds `useEffect` "just in case"

## Workflow

### 1. Identify the useEffect

Determine what the effect is doing -- deriving state, fetching data, responding to an event, syncing with an external system, or resetting state.

### 2. Apply the Correct Replacement Pattern

Use the five rules below to pick the right replacement.

### 3. Verify

```bash
bun --bun run typecheck -- --filter=<package>
bun --bun run test -- --filter=<package>
```

## The Escape Hatch: useMountEffect

For the rare case where you need to sync with an external system on mount:

The implementation wraps `useEffect` with an empty dependency array to make intent explicit:

```typescript
export function useMountEffect(effect: () => void | (() => void)) {
  /* eslint-disable no-restricted-syntax */
  useEffect(effect, []);
}
```

## Replacement Patterns

### Rule 1: Derive state, do not sync it

Most effects that set state from other state are unnecessary and add extra renders.

The rest: https://github.com/humanlayer/humanlayer/blob/HEAD/.claude/skills/no-use-effect/SKILL.md
