Understanding what every file in your Vite React project does โ and why โ gives you the confidence to modify the scaffold, add new files correctly, and debug problems when the build or runtime behaves unexpectedly. In this lesson you will walk through every file in the generated project, understand the relationship between index.html, main.jsx, and App.jsx, and reorganise the folder structure into the architecture the MERN Blog client will use throughout Part 4.
The Generated Files โ Explained
| File | Purpose | Do You Edit It? |
|---|---|---|
index.html |
HTML shell โ the single page React mounts into. Contains the <div id="root"> where React renders. |
Rarely โ add <meta> tags, title, fonts |
src/main.jsx |
Entry point โ imports React, ReactDOM, and App. Calls ReactDOM.createRoot().render() to mount the app. |
Rarely โ add global providers (Router, Context) |
src/App.jsx |
Root component โ the top of your component tree. Usually sets up routing. | Yes โ add routes, global layout |
src/index.css |
Global CSS โ applies to the whole application. | Yes โ add resets, CSS variables, base styles |
src/App.css |
Styles scoped to App.jsx. | Optional โ often deleted and replaced with a CSS Modules approach |
vite.config.js |
Vite configuration โ plugins, dev server proxy, build options. | Yes โ add proxy, aliases, plugins |
package.json |
Project manifest โ dependencies, scripts. | Yes โ add packages, update scripts |
public/ |
Static assets served at the root URL. Files here bypass Vite processing. | Yes โ add favicons, robots.txt, static images |
public/ and src/assets/: files in public/ are copied to dist/ as-is and served at their exact path (e.g. public/logo.png โ /logo.png). Files in src/assets/ are processed by Vite โ they get content-hashed filenames in the build, optimised, and tree-shaken. Import assets from src/assets/ when they are used in components; put truly static files (favicon, robots.txt) in public/.jsconfig.json (or tsconfig.json for TypeScript) at the client root with "paths": { "@/*": ["./src/*"] } and configure the same alias in vite.config.js. This gives you absolute imports: import Button from '@/components/ui/Button' instead of fragile relative paths like import Button from '../../../components/ui/Button'.src/ is processed by Vite and included in the bundle only if it is imported somewhere. Files that are not imported will be tree-shaken and excluded from the production build. If you add an image to src/assets/ but never import it in a component, it will not appear in the built site. Move truly standalone static files to public/ instead.index.html โ The HTML Shell
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>MERN Blog</title>
</head>
<body>
<!-- React mounts here โ this div is the entire SPA container -->
<div id="root"></div>
<!-- Vite injects the JS bundle here at build time -->
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
main.jsx โ The Entry Point
// src/main.jsx
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom'; // added in MERN Blog
import './index.css';
import App from './App.jsx';
createRoot(document.getElementById('root')).render(
<StrictMode>
<BrowserRouter> {/* Router wraps the entire app */}
<App />
</BrowserRouter>
</StrictMode>
);
The MERN Blog Client Structure
client/src/
โโโ assets/ โ Images, SVGs imported in components
โโโ components/ โ Reusable UI components (Button, Modal, PostCard...)
โ โโโ ui/ โ Generic UI primitives
โ โโโ layout/ โ Header, Footer, Sidebar, Layout wrapper
โโโ pages/ โ Page-level components (one per route)
โ โโโ HomePage.jsx
โ โโโ PostPage.jsx
โ โโโ LoginPage.jsx
โ โโโ RegisterPage.jsx
โโโ services/ โ Axios API call functions (one file per resource)
โ โโโ authService.js
โ โโโ postService.js
โโโ context/ โ React Context providers (AuthContext, ThemeContext)
โ โโโ AuthContext.jsx
โโโ hooks/ โ Custom hooks (usePosts, useAuth, useForm)
โ โโโ useAuth.js
โโโ utils/ โ Helper functions (formatDate, truncate...)
โ โโโ helpers.js
โโโ App.jsx โ Root component โ defines routes
โโโ main.jsx โ Entry point โ mounts React
โโโ index.css โ Global styles
Configuring Path Aliases in Vite
// client/vite.config.js
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import path from 'path';
export default defineConfig({
plugins: [react()],
resolve: {
alias: {
'@': path.resolve(__dirname, './src'), // @ โ src/
},
},
server: {
port: 5173,
proxy: {
'/api': { target: 'http://localhost:5000', changeOrigin: true },
},
},
});
// client/jsconfig.json โ for VS Code IntelliSense with the alias
{
"compilerOptions": {
"baseUrl": ".",
"paths": { "@/*": ["./src/*"] }
}
}
Common Mistakes
Mistake 1 โ Putting all components in one flat directory
โ Wrong โ all 30+ component files in src/components/ with no organisation:
src/components/
Header.jsx, Footer.jsx, Button.jsx, Modal.jsx, PostCard.jsx,
LoginForm.jsx, RegisterForm.jsx, PostForm.jsx...
// Finding a specific component requires scanning the whole list
โ Correct โ group by domain and responsibility from day one:
src/components/ui/ (Button, Input, Modal, Spinner)
src/components/layout/ (Header, Footer, Sidebar)
src/components/posts/ (PostCard, PostList, PostForm)
src/components/auth/ (LoginForm, RegisterForm)
Mistake 2 โ Writing API calls directly in component files
โ Wrong โ fetch calls scattered across component files:
// PostCard.jsx
useEffect(() => {
axios.delete(`/api/posts/${id}`, { headers: { Authorization: `Bearer ${token}` } });
}, []);
โ Correct โ centralise all API calls in service files:
// services/postService.js
export const deletePost = (id) => axios.delete(`/api/posts/${id}`);
// PostCard.jsx
import { deletePost } from '@/services/postService';
const handleDelete = () => deletePost(id);
Mistake 3 โ Not wrapping the app in BrowserRouter
โ Wrong โ using React Router hooks without a Router provider:
Error: useNavigate() may be used only in the context of a <Router> component
โ Correct โ wrap the entire app in BrowserRouter in main.jsx (already shown above).
Quick Reference
| File / Folder | Purpose |
|---|---|
index.html |
HTML shell with <div id="root"> |
src/main.jsx |
Entry point โ mounts React into the DOM |
src/App.jsx |
Root component โ routing and global layout |
src/pages/ |
One component per route |
src/components/ |
Reusable UI pieces |
src/services/ |
Axios API call functions |
src/context/ |
React Context providers |
src/hooks/ |
Custom React hooks |
public/ |
Static files (favicon, robots.txt) โ not processed by Vite |
vite.config.js |
Vite config โ proxy, aliases, plugins |