react-foundations — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited react-foundations (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Modern React development patterns for functional components, JSX, props, state, and hooks. All guidance targets current React practices — no class components or legacy lifecycle methods.
Components must be pure and idempotent — same inputs (props, state, context) always produce the same output. Side effects belong in event handlers or hooks like useEffect, never in the render path.
Allowed: Local mutation during rendering (creating and modifying arrays within the render function). Forbidden: Mutating external variables, DOM manipulation, or network requests during render.
htmlFor, tabIndex, classNamearia-label, data-testid<>...</>) to avoid wrapper divs that break semantic layoutProps are immutable snapshots for a single render. Never mutate them directly.
function Card({ title, children }) {}function Button({ variant = "primary" }) {} — do not use defaultProps or React.FCuseState does not auto-mergesetCount(prev => prev + 1)useState(() => computeExpensive())state.value = 2 does not trigger re-render — always use the setterHooks must follow strict rules so React can track state between renders:
Enforce with eslint-plugin-react-hooks — the rules-of-hooks and exhaustive-deps rules catch violations at build time.
`useEffect` is an escape hatch to synchronize with systems outside of React — not a lifecycle method and not a way to orchestrate data flow inside the component tree.
Ask why the code needs to run:
| Situation | Solution |
|---|---|
| Triggered by a specific user action (click, submit, type) | Event handler |
| Runs because the component was displayed on screen | `useEffect` |
| Syncing with external system (WebSocket, DOM, 3rd-party library) | `useEffect` |
| Updating state Y when state X changes | Calculate during render — never useEffect |
const fullName = firstName + ' ' + lastName; — no effect needed.AbortController + cleanup to cancel stale requests. Every fetch inside useEffect needs cancellation handling.user.id) or memoize with useCallback/useMemo to prevent unnecessary re-runs.// CORRECT: cleanup + AbortController
useEffect(() => {
const controller = new AbortController();
async function load() {
const data = await fetchUser(id, { signal: controller.signal });
setUser(data);
}
load();
return () => controller.abort();
}, [id]);
// WRONG: async directly as effect, no cleanup
useEffect(async () => { setUser(await fetchUser(id)); }, [id]);See references/detailed-patterns.md for the complete list of 15 useEffect mistakes with fixes.
If a value can be computed from existing props or state, it is NOT state. Never store it in useState and never sync it with useEffect.
// BAD: double render, brittle synchronization
const [fullName, setFullName] = useState('');
useEffect(() => setFullName(`${firstName} ${lastName}`), [firstName, lastName]);
// GOOD: calculated during render
const fullName = `${firstName} ${lastName}`;Use useMemo only if the calculation is provably expensive.
| Hook | Purpose | Key Pattern |
|---|---|---|
useState | Component memory | Functional updates: set(prev => ...) |
useEffect | Sync with external systems only | Always cleanup; use event handlers for user actions |
useRef | Mutable value that persists across renders | DOM refs, timers, previous values |
useMemo | Cache expensive computations | Only when measurably expensive; React Compiler handles the rest |
useCallback | Stable function references | When passing to React.memo-wrapped children |
useReducer | Complex state logic | Discriminated union actions with TypeScript |
useContext | Read context without nesting | Keep providers as deep in the tree as possible |
Extract reusable stateful logic into functions starting with use. Each call gets independent state.
useOnlineStatus(), useChatRoom(options)useMount(fn) — these bypass linting and break the React paradigmas const for correct TypeScript inference~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.