react — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited react (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.
Essential React 19 patterns for building modern applications with hooks, Suspense, lazy loading, and TypeScript.
Note: DSAI Component Convention (React 19):
forwardRef is REQUIRED for all DSAI components — use memo(forwardRef(function Name(props, ref))) patterndisplayName property*.types.ts filespropTypes removed (use TypeScript interfaces)React.FC type discouraged — use direct function components with typed propsimport { forwardRef, memo, useState, useCallback } from 'react';
import { cn } from '@/lib/utils';
import type { UserProfileProps } from './UserProfile.types';
// Props defined in UserProfile.types.ts:
// interface UserProfileProps {
// userId: string;
// onUpdate?: (data: UserData) => void;
// className?: string;
// }
export const UserProfile = memo(
forwardRef<HTMLDivElement, UserProfileProps>(
function UserProfile({ userId, onUpdate, className }, ref) {
const [data, setData] = useState<UserData | null>(null);
const handleUpdate = useCallback((newData: UserData) => {
setData(newData);
onUpdate?.(newData);
}, [onUpdate]);
return (
<div ref={ref} className={cn('user-profile', className)}>
{/* Component content */}
</div>
);
}
)
);
UserProfile.displayName = 'UserProfile';Creating a React component? Follow this:
memo(forwardRef(function Name(props, ref))) patterndisplayName on every component*.types.ts filecn() for class name composition (Bootstrap classes, not Tailwind)useCallback for event handlers passed to childrenuseMemo for expensive computationslazy(() => import())<Suspense> with fallback@/components/ui/ for DSAI componentsSee hooks-patterns.md for useState, useCallback, useMemo, and useEffect patterns with TypeScript examples.
See lazy-loading.md for React.lazy, Suspense fallbacks, and feature-based code splitting examples.
// Wrap data-fetching components
<Suspense fallback={<Skeleton />}>
<UserProfile userId={id} />
</Suspense>
// Nested Suspense for granular loading
<Suspense fallback={<PageLoader />}>
<Header />
<Suspense fallback={<ContentSkeleton />}>
<MainContent />
</Suspense>
<Footer />
</Suspense>import { ErrorBoundary } from 'react-error-boundary';
<ErrorBoundary fallback={<ErrorFallback />}>
<Suspense fallback={<Loading />}>
<DataComponent />
</Suspense>
</ErrorBoundary>See typescript-patterns.md for component props, hooks typing, and custom hook return types.
See performance.md for React.memo usage, custom comparison functions, and avoiding re-renders.
// Ternary operator
{isLoading ? <Spinner /> : <Content />}
// Logical AND
{error && <ErrorMessage error={error} />}
// Nullish coalescing
{user ?? <GuestView />}
// Early return for loading states
function Component() {
const { data } = useSomeHook();
// ❌ Avoid early returns for loading - breaks hooks rules
// Use Suspense instead
return <div>{data.map(...)}</div>;
}// Always use stable keys
{items.map(item => (
<ItemCard key={item.id} item={item} />
))}
// Never use index as key if list can reorder
// ❌ Bad
{items.map((item, index) => (
<ItemCard key={index} item={item} />
))}src/client/
├── components/
│ ├── ui/ # DSAI components (installed via `dsai add`)
│ │ ├── button/
│ │ │ ├── Button.tsx
│ │ │ ├── Button.types.ts
│ │ │ ├── Button.fsm.ts
│ │ │ └── index.ts
│ │ ├── modal/
│ │ └── card/
│ └── features/ # App-specific feature components
│ ├── auth/
│ └── posts/
├── hooks/ # Shared hooks (DSAI + custom)
├── lib/
│ └── utils/ # Utilities (cn, validators, etc.)
└── types/ # Shared typescomponents/ui/button/
├── Button.tsx # Component with forwardRef + displayName
├── Button.types.ts # TypeScript prop interfaces
├── Button.fsm.ts # FSM reducer (interactive components)
├── Button.test.tsx # Unit tests (Jest 30 + RTL)
├── Button.a11y.test.tsx # Accessibility tests (jest-axe)
└── index.ts # Barrel exportsSee common-mistakes.md for conditional hooks, missing dependencies, and state mutation anti-patterns.
For more detailed patterns, see:
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.