hermes

React component rules

Standing rules for React code an assistant writes, covering function components, the rules of hooks, colocated state, stable list keys, accessible markup and no effect-driven derived state.

When you write or change React components in this project:

Components

  • Write function components with hooks. Do not add class components.
  • Give each component one responsibility. Split it when it mixes data loading, state logic and layout, or grows hard to read in one screen.
  • Never define a component inside another component's body; it remounts on every render and loses its state.
  • Type props explicitly in TypeScript files. Do not spread unknown props onto DOM elements.
  • Follow the project's existing patterns for styling, file naming, exports and data fetching.

Hooks

  • Call hooks only at the top level of components and custom hooks, never inside conditions, loops or callbacks. Name custom hooks useSomething.
  • Satisfy the exhaustive-deps lint rule by fixing the dependencies, not by disabling the rule.

State

  • Keep state as close as possible to where it is used, and lift it only when siblings must share it.
  • Store the minimum. Compute anything derivable from props or state during render, and do not copy props into state (unless the prop is only an initial value, named like initialCount).
  • Reset a component's state by changing its key, not with an effect.
  • Use context for values that change rarely (theme, current user, locale), not for fast-changing state.
  • Never mutate state or props. Create new objects and arrays.

Effects

  • Use useEffect only to synchronise with something outside React: subscriptions, timers, imperative DOM or third-party widgets.
  • Never use an effect to compute derived state or to react to an event. Put event logic in the event handler.
  • Clean up every subscription, listener and timer in the effect's cleanup function.
  • Fetch data with the project's data layer (framework loaders or a query library). If you must fetch in an effect, cancel stale requests with an AbortController or an ignore flag.

Lists

  • Give list items a stable, unique key from the data, such as an id. Never use Math.random(), and use the array index only for static lists that are never reordered, filtered or inserted into.

Accessibility

  • Use semantic elements: button for actions, a with href for navigation, headings in order, lists for lists.
  • Never attach onClick to a div or span for an action; use a button.
  • Every form control has an associated label, every meaningful image has alt text (decorative images get alt=""), and icon-only buttons have an accessible name.
  • Custom widgets must be operable by keyboard, with visible focus. Dialogs move focus in and return it when closed.
  • Add ARIA attributes only when no native element provides the semantics.

Performance and safety

  • Do not wrap everything in useMemo, useCallback or memo. Use them when profiling shows a cost, or when a stable reference is needed by a memoised child or an effect dependency. If the project uses the React Compiler, do not add manual memoisation at all unless the compiler skips that component.
  • Never pass untrusted content to dangerouslySetInnerHTML. Sanitise it, or render it as text.

details

kind
Rule: standing instructions for everything the assistant does
domain
Software engineering
category
Conventions
made for
Frontend engineer, Full-stack engineer, Software engineer
risk
read-only
version
v1.0.0 · experimental
reviewed
2026-10-02
works in
Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Antigravity, OpenCode, Windsurf, Zed, Continue, AGENTS.md, ChatGPT, claude.ai

Edit on GitHubReport a problem

use in

Hodios CLI
npx @hermes-hq/hodios install react-component-rules --target claude-code
Agent Skills
npx skills add hermes-hq/hodios-dist --skill react-component-rules -a claude-code

Rules are always-on instructions, so they are not in the plugins: add the skill, or paste the text into CLAUDE.md.

pairs well with

All of Conventions
RuleTesting

Test-writing rules

Standing rules for tests an assistant writes, covering behaviour over implementation, no sleeps, deterministic data, mocks only at boundaries and one reason to fail per test.

test-writing-rules
RuleConventions

HTTP API design rules

Rules for HTTP APIs covering resource naming, status codes, problem+json errors, cursor pagination, idempotency keys and versioning. Load when designing or changing HTTP endpoints.

api-design-rules
RuleConventions

C# style rules

Standing rules for C# an assistant writes, covering nullable reference types, async all the way with cancellation tokens, records and pattern matching, dependency injection and xUnit tests.

csharp-style-rules
RuleConventions

Go style rules

Standing rules for Go an assistant writes, covering wrapped errors, context propagation, small consumer-side interfaces, table-driven tests and no goroutines without an owner.

go-style-rules
RuleConventions

Java style rules

Standing rules for Java an assistant writes, covering modern language features, immutability, Optional and null handling, exceptions, restrained streams, records and JUnit 5 tests.

java-style-rules
RuleConventions

Python style rules

Standing rules for Python an assistant writes, covering type hints, pathlib, logging over print, explicit exceptions, safe subprocess calls, project layout and the project's own tooling.

python-style-rules