rules
React Next.js Patterns
Next.js App Router patterns: Server Components by default, push "use client" down, thin pages, and React Compiler-first memoization.
ruledev-ted
ted-craft — zsh
$ npx ted-craft add react-nextjs-patterns -a cursor -g -y---
description: React and Next.js App Router patterns for components, pages, and composition
globs:
- "**/*.{tsx,jsx}"
- "**/app/**/*.{ts,tsx,js,jsx}"
alwaysApply: true
---
# React & Next.js — Components & Pages
**Assumes:** Next.js App Router. Cross-refs: `react-project-structure`, `react-shadcn-components`, `react-ui-decisions`, `react-tanstack-query`, `react-accessibility`, `react-no-framer-motion`.
## Server vs Client
- **`page.tsx`**, **`layout.tsx`**, and **`route.ts`** are **Server Components by default** (no `"use client"` at the top). Keep them that way unless they need hooks, browser APIs, or event handlers.
- Add **`"use client"`** at the **first line** of a module when it uses **`useState`**, **`useEffect`**, **`useRef`**, event handlers (`onClick`, `onChange`), **TanStack Query** (`useQuery`, `useMutation`), client-only context, or **`window` / `document` / `localStorage`**.
- **Push `"use client"` down the tree**: prefer a small client **leaf** (form, table, modal) imported into a server page rather than marking the whole page client-only without reason.
- **Providers** (query, theme, auth) are client components wrapping the app from a root layout—do not nest duplicate providers without a clear need.
## Creating Components
- Use **function components** only; type **`props`** with a **`interface`** or **`type`** at the top of the file or next to the component.
- **Primitives** live in the project’s shared UI folder (often `src/components/ui` or `src/components/common`). **Feature UI** lives under domain/feature folders—see `react-shadcn-components`.
- Prefer **composition** (children, slots, small subcomponents) over props drilling deep trees; extract hooks when logic is reused.
- Match **existing naming** in the folder you add to.
- Preserve **`ref`** forwarding when wrapping primitives (`React.ComponentProps`, `forwardRef` patterns already used).
## React Compiler & Memoization
- If the app enables the **React Compiler** (`reactCompiler` in Next config or equivalent), treat automatic memoization as the default optimisation story.
- **Do not** add **`useCallback`**, **`useMemo`**, or **`React.memo`** “just in case” for performance. Use normal inline functions and derived values unless you have a **concrete** reason.
- **Rare exceptions:** keep **`useMemo` / `useCallback`** only when something **requires a stable identity** that the compiler cannot infer (e.g. a third-party API that compares references). Prefer fixing the underlying pattern first; add a **one-line comment** if you must keep the hook.
- If the compiler is **not** enabled, still avoid gratuitous memoization—measure first.
## Creating Pages (`app/`)
- **`page.tsx`**: **`export default`** the page component. Export **`metadata`** / **`generateMetadata`** from **server** page modules when SEO/titles are needed (not from client components).
- Keep **pages thin**: assemble layout sections and pass data or callbacks into **components**. Avoid thousand-line **`page.tsx`** files—lift UI into named components.
- Use **route groups** when the project already does; do not break URL structure when adding routes.
- **`layout.tsx`** wraps **`children`** only; shared chrome (sidebar, nav) belongs in the **group layout**, not duplicated per page.
## Using Components on Pages
- Import with the project’s path alias (commonly **`@/`**).
- **Server page → client child** is normal: the page can fetch or pass serialisable **props** into a client component. Do not pass **functions** from server to client except **Server Actions** where that pattern is established.
- For **client data**, use TanStack Query (or equivalent) inside **`"use client"`** components, not inside server **`page.tsx`** (see `react-tanstack-query`).
- **Loading UX**: use **`Suspense`** boundaries and/or the project **`Skeleton`** primitive. Route-level **`loading.tsx`** / **`error.tsx`** when a route needs a dedicated shell.
## Quick Checklist
- [ ] **`"use client"`** only where required; boundary as low as possible.
- [ ] **Page** orchestrates; **components** implement UI and client state.
- [ ] **Data**: server fetch in RSC when appropriate; **React Query** only in client modules.
- [ ] Shared primitives from the configured UI folder; feature UI in feature folders.
- [ ] **Accessibility** and **responsive** rules respected (`react-accessibility`, `react-responsive-design`).
- [ ] No **gratuitous** **`useMemo` / `useCallback` / `memo`** when the React Compiler is enabled.React & Next.js — Components & Pages
Assumes: Next.js App Router. Cross-refs: react-project-structure, react-shadcn-components, react-ui-decisions, react-tanstack-query, react-accessibility, react-no-framer-motion.
Server vs Client
page.tsx,layout.tsx, androute.tsare Server Components by default (no"use client"at the top). Keep them that way unless they need hooks, browser APIs, or event handlers.- Add
"use client"at the first line of a module when it usesuseState,useEffect,useRef, event handlers (onClick,onChange), TanStack Query (useQuery,useMutation), client-only context, orwindow/document/localStorage. - Push
"use client"down the tree: prefer a small client leaf (form, table, modal) imported into a server page rather than marking the whole page client-only without reason. - Providers (query, theme, auth) are client components wrapping the app from a root layout—do not nest duplicate providers without a clear need.
Creating Components
- Use function components only; type
propswith ainterfaceortypeat the top of the file or next to the component. - Primitives live in the project’s shared UI folder (often
src/components/uiorsrc/components/common). Feature UI lives under domain/feature folders—seereact-shadcn-components. - Prefer composition (children, slots, small subcomponents) over props drilling deep trees; extract hooks when logic is reused.
- Match existing naming in the folder you add to.
- Preserve
refforwarding when wrapping primitives (React.ComponentProps,forwardRefpatterns already used).
React Compiler & Memoization
- If the app enables the React Compiler (
reactCompilerin Next config or equivalent), treat automatic memoization as the default optimisation story. - Do not add
useCallback,useMemo, orReact.memo“just in case” for performance. Use normal inline functions and derived values unless you have a concrete reason. - Rare exceptions: keep
useMemo/useCallbackonly when something requires a stable identity that the compiler cannot infer (e.g. a third-party API that compares references). Prefer fixing the underlying pattern first; add a one-line comment if you must keep the hook. - If the compiler is not enabled, still avoid gratuitous memoization—measure first.
Creating Pages (app/)
page.tsx:export defaultthe page component. Exportmetadata/generateMetadatafrom server page modules when SEO/titles are needed (not from client components).- Keep pages thin: assemble layout sections and pass data or callbacks into components. Avoid thousand-line
page.tsxfiles—lift UI into named components. - Use route groups when the project already does; do not break URL structure when adding routes.
layout.tsxwrapschildrenonly; shared chrome (sidebar, nav) belongs in the group layout, not duplicated per page.
Using Components on Pages
- Import with the project’s path alias (commonly
@/). - Server page → client child is normal: the page can fetch or pass serialisable props into a client component. Do not pass functions from server to client except Server Actions where that pattern is established.
- For client data, use TanStack Query (or equivalent) inside
"use client"components, not inside serverpage.tsx(seereact-tanstack-query). - Loading UX: use
Suspenseboundaries and/or the projectSkeletonprimitive. Route-levelloading.tsx/error.tsxwhen a route needs a dedicated shell.
Quick Checklist
-
"use client"only where required; boundary as low as possible. - Page orchestrates; components implement UI and client state.
- Data: server fetch in RSC when appropriate; React Query only in client modules.
- Shared primitives from the configured UI folder; feature UI in feature folders.
- Accessibility and responsive rules respected (
react-accessibility,react-responsive-design). - No gratuitous
useMemo/useCallback/memowhen the React Compiler is enabled.