Install any skill in seconds. Free to start, no credit card required.
Get Started Free →React enterprise architecture guidelines for structuring scalable, production-grade applications. Use when scaffolding a new React project, reviewing project structure, setting up feature slices, choosing state management, configuring data fetching, or making architectural decisions in a React/TypeScript codebase. Covers folder structure, routing (TanStack Router, React Router v7, Next.js App Router), TanStack Query v5, Zustand, React Compiler, Vite 6, Turbopack, Vitest, Playwright, Tailwind v4,
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 177% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 155% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 197% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 259% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 174% | 0% |
Feature-first, enterprise-grade React architecture that scales across teams and codebases. Assumes TypeScript strict, modern tooling (Vite 6 or Next.js 16 App Router), and emphasizes feature isolation, data-access boundaries, performance, and operability.
src/
app/
providers/ # app-level providers (query client, i18n, theme)
routing/ # router setup & guards
layouts/ # app chrome (top bar, sidebar, auth shell)
config/ # runtime config loader & tokens
errors/ # boundary, fallback UI, error instrumentation
shared/ # reusable & stateless UI/utilities
ui/ # presentational components (buttons, cards, table)
forms/ # form controls, hooks, schemas, validators
hooks/ # generic hooks not tied to a feature
utils/ # pure TS helpers
styles/ # design tokens, mixins, global CSS
features/ # domain-driven feature slices (lazy where possible)
users/
index.ts # public API for the feature
routes.tsx # feature routes (SPA) or page segments (Next.js)
components/ # presentational, feature-scoped
pages/ # feature shells/screens
api/ # data-access (clients, models, adapters)
state/ # local store/facade (Zustand)
testing/ # test builders/mocks
test/ # global test utilities
main.tsx # app bootstrap (SPA) or entry (Next.js client)Philosophy
> Next.js (App Router): Map features to app/(features)/<feature> segments and keep UI/data boundaries the same. For an SPA, use TanStack Router or React Router v7 + Vite 6.
app/providers to host QueryClientProvider, ThemeProvider, I18nProvider, StoreProvider, etc./config.json (or env) early; expose via a typed context or simple module.ErrorBoundary + error reporting (Sentry, etc.).app/layouts/, not in shared or features. Use <Outlet /> (React Router) or {children} (Next.js) for content slots.Example (SPA, Vite 6)
tsx// main.tsx createRoot(document.getElementById('root')!).render( <StrictMode> <AppProviders> <RouterProvider router={appRouter} /> </AppProviders> </StrictMode> );
shared/
ui/
PageHeader/
DataTable/
EmptyState/
Skeleton/
forms/
Form/
TextField/
PhoneInput/
validators.ts
hooks/
useDebounce.ts
useToggle.ts
utils/
date.ts
array.ts
styles/
tokens.css
globals.cssRules
> React Compiler note: With React Compiler stable (1.0), manual React.memo wrapping is no longer needed in most cases. The compiler auto-memoizes at the expression level. Retain manual memoization only at third-party library interop boundaries where identity comparison is explicitly required.
Each feature encapsulates UI, data-access, and local state.
features/users/
index.ts # exports public units (components/hooks)
routes.tsx # SPA route config for this feature
pages/
UsersListPage.tsx # screen/shell: orchestrates data + renders UI
UserCreatePage.tsx
UserEditPage.tsx
components/
UsersTable.tsx # presentational
UserCard.tsx
UserForm.tsx # shared between create/edit
api/
users.client.ts # HTTP client
users.models.ts # DTOs & ViewModels
users.adapter.ts # DTO <-> VM mappings
queries.ts # TanStack Query v5 hooks
state/
users.store.ts # Zustand store for UI state
testing/
builders.tsRules
index.ts.defaultValues and an onSubmit handler.['users', 'list']).useSuspenseQuery for simpler loading states with <Suspense> boundaries.v5 key changes from v4:
onSuccess/onError/onSettled callbacks removed from useQuery — handle in calling code.keepPreviousData removed — use placeholderData: (prev) => prev.useErrorBoundary renamed to throwOnError.initialPageParam.Example
ts// features/users/api/queries.ts export const usersKeys = { all: ['users'] as const, list: () => [...usersKeys.all, 'list'] as const, detail: (id: string) => [...usersKeys.all, 'detail', id] as const, }; export function useUsers() { return useSuspenseQuery({ queryKey: usersKeys.list(), queryFn: api.users.list, }); } export function useCreateUser() { const qc = useQueryClient(); return useMutation({ mutationFn: api.users.create, onSuccess: () => qc.invalidateQueries({ queryKey: usersKeys.all }), }); }
| State type | Solution | |---|---| | Server cache | TanStack Query v5 — do not mirror into client stores | | Local UI state | useState / useReducer inside components | | Cross-feature client state (auth, theme, feature flags) | Zustand (lightweight, ~3KB) | | Complex atomic state (many interdependent values) | Jotai (fine-grained reactivity) | | Legacy large codebases | Redux Toolkit + feature slices (maintain, don't adopt fresh) |
api/.app/providers.Example
ts// users.adapter.ts export const toUserVM = (dto: UserDto): UserVM => ({ id: dto.id, name: `${dto.firstName} ${dto.lastName}`, role: dto.role ?? 'user', });
Type-safe routes, params, and search params with full inference and autocomplete. Built-in data loading and caching. DevTools included.
Library mode for traditional SPA. Adequate for most use cases; lacks built-in type-safe params.
Feature routes under app/(features)/users with page.tsx per route. Use route groups for layout boundaries.
Layout pattern:
app/layouts/ — not feature code.PageHeader renders inside each page's <main> content area.app/
layout.tsx # global minimal layout/providers
(dashboard)/
layout.tsx # top bar + sidebar + {children}
users/
page.tsx # list
new/page.tsx # create
[id]/edit/page.tsx # edit
(public)/
layout.tsx
login/page.tsxReact Compiler 1.0 is stable (October 2025). It is a build-time Babel plugin that performs automatic expression-level memoization via static analysis.
Impact on your code:
useMemo, useCallback, and React.memo are largely unnecessary for new code.react-compiler-runtime.Adoption:
reactCompiler: true in next.config.ts).children pattern).@tanstack/react-virtual), and stable item render.<ViewTransition> (canary): Wraps browser View Transitions API for smooth route animations. Safe to experiment, not production-critical yet.<Suspense> for granular loading states and streaming.dangerouslySetInnerHTML.Secure, HttpOnly cookies where possible; rotate and refresh securely.shared/styles.| Layer | Tool | Notes | |---|---|---| | Unit / Component | Vitest + React Testing Library | Co-locate *.test.ts(x) with code. Vitest is ~6x faster cold start than Jest, native ESM/TS support. | | API mocking | MSW (Mock Service Worker) | Intercept at the network level for realistic mocks. | | Integration | Vitest + real providers (QueryClient, Router) | Test screens with actual provider tree. | | E2E | Playwright | 3-5 critical flows in CI. UI Mode for time-traveling debugger. |
features/*/testing and test/.| Tool | Use case | |---|---| | Vite 6 | Standalone React SPAs. Fastest HMR, broadest plugin support. Environment API for multi-target dev. | | Turbopack | Next.js projects. Default bundler in Next.js 16. | | Rspack | Webpack migration without full rewrite (Rust-based, Webpack-compatible). |
@app, @shared, @features/*.features/*/index.ts public API.type:feature, type:shared).json{ "paths": { "@app/*": ["src/app/*"], "@shared/*": ["src/shared/*"], "@features/*": ["src/features/*"] } }
import.meta.env / Next.js process.env) for non-sensitive flags./config.json (or server) at startup.tsx// features/users/routes.tsx export const usersRoute = createRoute({ getParentRoute: () => dashboardRoute, path: '/users', component: UsersListPage, }); export const userCreateRoute = createRoute({ getParentRoute: () => dashboardRoute, path: '/users/new', component: UserCreatePage, }); export const userEditRoute = createRoute({ getParentRoute: () => dashboardRoute, path: '/users/$id/edit', component: UserEditPage, });
tsx// features/users/pages/UsersListPage.tsx export function UsersListPage() { const { data } = useUsers(); // useSuspenseQuery return ( <main className="container"> <PageHeader title="Users" subtitle="Manage accounts" /> <UsersTable users={data} /> </main> ); }
tsx// Create <main className="container"> <PageHeader title="Add User" /> <UserForm onSubmit={(input) => createUser.mutate(input)} /> </main> // Edit <main className="container"> <PageHeader title="Edit User" /> <UserForm defaultValues={toFormValues(user)} onSubmit={(input) => updateUser.mutate({ id, input })} /> </main>
src/app/layouts/
AppLayout.tsx # top bar + sidebar + <Outlet />
AuthLayout.tsxtsxconst router = createBrowserRouter([ { element: <AppLayout />, children: [ { path: '/users', element: <UsersListPage /> }, { path: '/users/new', element: <UserCreatePage /> }, { path: '/users/:id/edit', element: <UserEditPage /> }, { index: true, element: <Navigate to="/users" replace /> }, ], }, { element: <AuthLayout />, children: [{ path: '/login', element: <LoginPage /> }], }, ]);
| Layer | Purpose | Rules | |---|---|---| | app/ | Wiring (routing, providers, layouts, config) | No feature code here | | shared/ | Stateless UI + generic hooks/utils | No data fetching/HTTP | | features/ | Domain UI + data + local store | Export via index.ts | | test/ | Global test utils | Reuse across features |
| Concern | Tool | |---|---| | Framework | Vite 6 (SPA) or Next.js 16 (SSR/RSC) | | Language | TypeScript 5.8+ strict | | Compiler | React Compiler 1.0 | | Routing (SPA) | TanStack Router (new) / React Router v7 (existing) | | Server cache | TanStack Query v5 | | Client state | Zustand | | Forms | React Hook Form | | Styling | Tailwind CSS v4 + shadcn/ui | | Unit testing | Vitest + React Testing Library | | E2E testing | Playwright | | API mocking | MSW | | Monorepo | Nx or Turborepo |
Other measured skills in the registry, with their headline benchmark lift.