react-app/
├── public/
├── src/
│ ├── assets/
│ │ ├── fonts/
│ │ ├── icons/
│ │ └── images/
│ ├── components/
│ │ ├── forms/
│ │ ├── layout/
│ │ └── ui/
│ ├── features/
│ │ ├── auth/
│ │ │ ├── components/
│ │ │ ├── hooks/
│ │ │ ├── services/
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ ├── dashboard/
│ │ └── settings/
│ ├── hooks/
│ ├── lib/
│ ├── pages/
│ ├── routes/
│ ├── services/
│ ├── stores/
│ ├── types/
│ ├── utils/
│ ├── App.tsx
│ ├── index.css
│ ├── main.tsx
│ └── vite-env.d.ts
├── tests/
│ ├── e2e/
│ ├── integration/
│ └── unit/
├── .env
├── .gitignore
├── eslint.config.js
├── index.html
├── package.json
├── README.md
├── tsconfig.json
└── vite.config.ts
Shared, reusable components used across multiple features.
ui/— Primitive UI components (Button, Input, Modal, Card, etc.)layout/— Structural components (Header, Footer, Sidebar, RootLayout)forms/— Reusable form components (FormField, Select, DatePicker)
Key principle: Components here are feature-agnostic and highly reusable.
Feature-based organization — the heart of the architecture. Each feature is a self-contained module with everything it needs.
features/
└── auth/
├── components/ # Feature-specific components
├── hooks/ # Feature-specific hooks
├── services/ # API calls for this feature
├── types.ts # TypeScript types for this feature
└── index.ts # Public API (barrel export)
Why this pattern?
- Colocation keeps related code together
- Easy to find, modify, or delete entire features
- Clear boundaries between domains
- Each
index.tsacts as a public API — only export what other features need
public/— Static assets served as-is, copied directly to build outputsrc/assets/— Bundler-processed assets (images, fonts, icons)src/hooks/— Global custom hooks shared across featuressrc/lib/— Third-party library configs (Axios instance, Query client)src/pages/— Route-level components, one per route. Keep thin; logic belongs in featuressrc/routes/— React Router config, protected routes, route definitionssrc/services/— Global API services for cross-cutting concernssrc/stores/— Global state management (Zustand/Jotai/Redux)src/types/— Global TypeScript types shared across the appsrc/utils/— Pure utility functions (formatters, validators, constants)tests/— Unit, integration, and e2e tests
- Feature-first organization — Group by domain, not by type
- Colocation — Keep related files together
- Barrel exports — Use
index.tsto control public APIs - Separation of concerns — Pages compose, features contain logic, components display
- Flat where possible — Avoid deep nesting beyond 3-4 levels
| Concern | Recommended |
|---|---|
| Build tool | Vite |
| Routing | React Router v6+ |
| State | Zustand or Jotai |
| Server state | TanStack Query |
| Styling | Tailwind CSS |
| Forms | React Hook Form + Zod |
| Testing | Vitest + Testing Library + Playwright |