
React Skills
- 11 installs
- 1 repo stars
- Updated July 23, 2026
- mym0404/agent-skills
Helps with frontend development tasks.
About
react-skills is a Claude Code skill for frontend development. It helps developers move faster with AI-assisted coding.
- react-skills
- Frontend Development
- AI-coding skill
React Skills by the numbers
- 11 all-time installs (skills.sh)
- Ranked #1,658 of 2,245 Frontend Development skills by installs in the Skillselion catalog
- Data as of Jul 24, 2026 (Skillselion catalog sync)
npx skills add https://github.com/mym0404/agent-skills --skill react-skillsAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 11 |
|---|---|
| repo stars | ★ 1 |
| Last updated | July 23, 2026 |
| Repository | mym0404/agent-skills ↗ |
What it does
Helps with frontend development tasks.
Files
React Skills
Ruleset for React data fetching patterns and guide-driven utility refactoring.
Rule Categories by Priority
| Priority | Category | Impact | Prefix |
|---|---|---|---|
| 1 | Data Fetching | HIGH | data- |
| 2 | React Util | HIGH | react-util- |
Quick Reference
data-server-first-fetching- Fetch data in Server Components firstdata-async-boundary-suspense-query- Use AsyncBoundary with useSuspenseQuery for client data fetchingreact-util-usage- Use upstreamllms.txtto discover and apply@mj-studio/react-utilhelpers instead of bespoke React utility code
How to Use
Read the rule files:
rules/data-server-first-fetching.md
rules/data-async-boundary-suspense-query.md
rules/react-util-usage.mdinterface:
display_name: "React Skills"
short_description: "React data fetching and react-util guidance"
default_prompt: "Use $react-skills to implement the preferred React data fetching pattern."
policy:
allow_implicit_invocation: false
{
"version": "2.1.2",
"organization": "Engineering",
"date": "March 2026",
"abstract": "React data fetching best practices plus guide-driven refactoring rules for adopting @mj-studio/react-util hooks and components.",
"references": [
"https://nextjs.org/docs/app/building-your-application/data-fetching",
"https://suspensive.org/en/docs/react/Suspense",
"https://tanstack.com/query/latest/docs/framework/react/reference/useSuspenseQuery",
"https://suspensive.org/en/docs/react/migration/migrate-to-v2",
"https://github.com/mj-studio-library/react-util",
"https://github.com/mj-studio-library/react-util/blob/master/llms.txt"
]
}
Sections
1. Data Fetching (data)
Impact: HIGH Description: Prefer Server Components for initial data loading.
2. React Util (react-util)
Impact: HIGH Description: Guide-driven rules for adopting @mj-studio/react-util helpers to simplify and refactor React code.
Use AsyncBoundary with useSuspenseQuery for Client Data Fetching
This pattern is exclusively for client-side rendering contexts — React Native apps and web 'use client' components. Do NOT use in Server Components or SSG/ISR pages where data should be fetched at build time or request time on the server (see data-server-first-fetching rule instead).
Wrap client-side data fetching components with AsyncBoundary (ErrorBoundary + Suspense) and use useSuspenseQuery inside. Separate the boundary (outer) from the data consumer (inner) so loading and error states are handled declaratively, not imperatively.
AsyncBoundary Component
Combine @suspensive/react's ErrorBoundary and Suspense into a single reusable boundary:
'use client';
import { ErrorBoundary, Suspense } from '@suspensive/react';
import type { ComponentProps, ReactNode } from 'react';
type AsyncBoundaryProps = {
children: ReactNode;
pendingFallback?: ReactNode;
rejectedFallback?: ComponentProps<typeof ErrorBoundary>['fallback'];
clientOnly?: boolean;
ignoreError?: boolean;
};
export const AsyncBoundary = ({
children,
pendingFallback = <DefaultPendingFallback />,
rejectedFallback = ({ error, reset }) => <DefaultRejectedFallback error={error} reset={reset} />,
clientOnly = false,
ignoreError = false,
}: AsyncBoundaryProps) => {
return (
<ErrorBoundary fallback={ignoreError ? null : rejectedFallback}>
<Suspense clientOnly={clientOnly} fallback={pendingFallback}>
{children}
</Suspense>
</ErrorBoundary>
);
};clientOnly— delays rendering until the client, preventing SSR hydration mismatches for auth-dependent or browser-only data.ignoreError— silently swallows errors (useful for non-critical UI sections like activity feeds).
Usage Pattern: Boundary ↔ Consumer Separation
Incorrect — imperative loading/error handling inside the component:
'use client';
import { useEffect, useState } from 'react';
export const CommentSection = ({ postId }: { postId: string }) => {
const [comments, setComments] = useState<Comment[]>([]);
const [isLoading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
fetchComments(postId)
.then(setComments)
.catch(setError)
.finally(() => setLoading(false));
}, [postId]);
if (isLoading) {
return <Spinner />;
}
if (error) {
return <p>{error.message}</p>;
}
return <CommentList comments={comments} />;
};Problems: loading/error state scattered across component logic, no automatic retry on error, no cache, refetch on mount every time.
Correct — declarative boundary + suspense query:
'use client';
import { useSuspenseQuery } from '@tanstack/react-query';
import { AsyncBoundary } from '@/lib/component/AsyncBoundary';
// Outer: provides loading/error boundary
export const CommentSection = ({ postId }: { postId: string }) => {
return (
<AsyncBoundary
clientOnly
pendingFallback={
<div className={'flex min-h-[200px] items-center justify-center'}>
<span className={'loading loading-ring loading-lg'} />
</div>
}
>
<CommentSectionContent postId={postId} />
</AsyncBoundary>
);
};
// Inner: assumes data is always available — no loading/error checks
const CommentSectionContent = ({ postId }: { postId: string }) => {
const { comments } = useComments(postId);
return <CommentList comments={comments} />;
};
// Hook: encapsulates query logic
const useComments = (postId: string) => {
const { data } = useSuspenseQuery({
queryKey: ['comments', postId],
queryFn: async () => {
const res = await fetch(`/api/comments?postId=${postId}`);
if (!res.ok) {
throw new Error('Failed to fetch comments');
}
return (await res.json()) as Comment[];
},
});
return { comments: data };
};Key Rules
1. Client-only pattern — this entire pattern (AsyncBoundary + useSuspenseQuery) applies only to React Native or web client components ('use client'). In Server Components or SSG/ISR pages, fetch data directly on the server without Suspense boundaries or TanStack Query. 2. Outer boundary, inner consumer — the component that renders AsyncBoundary never calls useSuspenseQuery itself. A child component consumes the data. 2. Use `clientOnly` for auth-dependent or browser-only queries — prevents SSR from attempting to render before the client has session state. 3. Use `ignoreError` only for non-critical sections — activity feeds, optional panels. Never for primary page content. 4. Custom `pendingFallback` per context — match the loading skeleton to the section's visual layout (card skeleton for cards, table skeleton for tables). 5. `useSuspenseQuery` from `@tanstack/react-query` — not from @suspensive/react-query (deprecated re-exports). Import directly from TanStack. 6. Throw errors in `queryFn` — useSuspenseQuery propagates thrown errors to the nearest ErrorBoundary. Never swallow fetch errors silently. 7. Never use in Server Components or SSG — Server Components can await data directly. SSG/ISR pages use fetch with caching options at build/request time. Using AsyncBoundary + useSuspenseQuery there is unnecessary and will not work as expected.
Nested AsyncBoundary
Multiple AsyncBoundary wrappers can be nested for independent loading states:
export default function ProfilePage() {
return (
<AsyncBoundary clientOnly>
<ProfileContent />
{/* Nested boundary for secondary section */}
<AsyncBoundary clientOnly pendingFallback={<CardSkeleton />}>
<MyCommentsList userId={profile.id} />
</AsyncBoundary>
</AsyncBoundary>
);
}Each boundary isolates its own loading/error state — a failure in MyCommentsList won't take down ProfileContent.
Reference:
Prefer Server-First Fetching
Load primary route data in Server Components before introducing client-side fetch logic.
Incorrect:
"use client"
import { useEffect, useState } from "react"
export default function DashboardPage() {
const [stats, setStats] = useState<{ users: number }>({ users: 0 })
useEffect(() => {
fetch("/api/stats").then(async (res) => {
setStats((await res.json()) as { users: number })
})
}, [])
return <p>{stats.users}</p>
}Correct:
export default async function DashboardPage() {
const res = await fetch("https://example.com/api/stats", {
next: { revalidate: 60 },
})
const stats = (await res.json()) as { users: number }
return <p>{stats.users}</p>
}Reference: Next.js Data Fetching
@mj-studio/react-util Guide-Driven Refactoring
When React utility logic is being added, reviewed, or refactored, check whether @mj-studio/react-util already documents a public hook or component that can replace custom lifecycle, timer, stable-callback, client-only, or browser-event code. The point of this rule is not to restate the guide locally, but to make the guide actively shape implementation and refactoring decisions.
Guide reference:
Required Workflow
1. Open the upstream llms.txt before adding or refactoring React utility logic in the domains covered by @mj-studio/react-util. 2. If the user explicitly requests using @mj-studio/react-util and the package is not installed in the project, install it first. 3. Check whether an existing public hook or component can replace the local code with a simpler and clearer implementation. 4. If the documented helper matches the intended semantics, prefer refactoring to that helper instead of keeping bespoke React utility code. 5. Use the guide to discover supported patterns and best practices, then apply them directly in the project code. 6. Re-check llms.txt whenever behavior, options, naming, or runtime assumptions are uncertain.
Do Not
- Do not treat
@mj-studio/react-utilas a passive reference only. Use it to simplify React code when it is a good semantic match. - Do not install the package proactively when the user did not ask to use
@mj-studio/react-util. - Do not keep ad-hoc hooks or wrapper components if the package already provides the same behavior clearly.
- Do not wrap or recreate documented helpers without a concrete project-specific reason.
- Do not paraphrase all function and component docs into this skill. Keep this rule focused on when and how to apply the upstream guide.
This rule applies to every public hook and component from @mj-studio/react-util. The upstream llms.txt should be used as the working guide for discovering replacement opportunities, simplifying existing React code, and standardizing utility usage across the project.
Reference: Repository @mj-studio/react-util llms.txt