Roadmap › React (with Hooks, React 19 & Next.js basics) › Module: Fundamentals
Lessons in this course (17)
5. React project folder structure — with sample files (Vite + TypeScript)
Basic★ Must knowLesson 5 of 17
npm create vite@latest shop-ui -- --template react-ts creates a client-side React app. A real project grows into a feature-based structure:
text
shop-ui/
├── index.html the single HTML page; <div id="root"> where React mounts
├── public/ static files copied as-is (favicon, robots.txt)
├── src/
│ ├── main.tsx entry point: createRoot(...).render(<App />) with providers (Router, QueryClient)
│ ├── App.tsx root component: layout + routes
│ ├── routes.tsx route table (React Router)
│ ├── index.css global styles
│ ├── assets/ images/fonts imported by components
│ ├── components/ shared, reusable UI
│ │ ├── ui/Button.tsx, Modal.tsx, Spinner.tsx
│ │ └── layout/Header.tsx, Footer.tsx
│ ├── features/ one folder per business feature
│ │ ├── products/
│ │ │ ├── api.ts calls to the backend API (fetch/axios)
│ │ │ ├── types.ts Product, PagedResult<T>
│ │ │ ├── useProducts.ts custom hook (TanStack Query)
│ │ │ ├── ProductList.tsx page/feature component
│ │ │ ├── ProductCard.tsx
│ │ │ └── ProductList.test.tsx
│ │ └── orders/ …
│ ├── hooks/ shared custom hooks (useDebounce, useAuth)
│ ├── lib/ apiClient.ts (base URL, auth header), utils
│ ├── store/ global client state (Zustand / Redux Toolkit) if needed
│ └── types/ shared types
├── .env.development / .env.production VITE_API_URL=...
├── vite.config.ts dev server, proxy to the API, build settings
├── tsconfig.json · eslint.config.js · package.jsontsx
// src/main.tsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { BrowserRouter } from "react-router-dom";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import App from "./App";
import "./index.css";
const queryClient = new QueryClient();
createRoot(document.getElementById("root")!).render(
<StrictMode>
<QueryClientProvider client={queryClient}>
<BrowserRouter><App /></BrowserRouter>
</QueryClientProvider>
</StrictMode>
);
// src/App.tsx
import { Routes, Route } from "react-router-dom";
import Header from "./components/layout/Header";
import ProductList from "./features/products/ProductList";
export default function App() {
return (
<>
<Header />
<Routes>
<Route path="/" element={<ProductList />} />
<Route path="*" element={<p>Not found</p>} />
</Routes>
</>
);
}Next.js projects use the app/ folder conventions instead (see the Next.js course).