Your First React App with Vite (Part 2) #08
📖 Introduction
Following our successful scaffolding of a new React project in Your First React App with Vite (Part 1), this article, Part 2, will take a deeper dive into the initial project structure generated by Vite. We'll explore the key files and folders, focusing on how your "Hello World" application is rendered from index.html
through main.jsx
to App.jsx
. Understanding this foundational flow is crucial for building and organizing your React applications effectively.
📚 Prerequisites
Before we begin, please ensure you have a solid grasp of the following concepts:
- Article 7 Concepts: You should have successfully created and run your first Vite React application.
- HTML Structure: Basic understanding of HTML elements and how a browser renders them.
- JavaScript Modules: Familiarity with
import
andexport
statements in JavaScript. - React Components: A basic understanding of what a React component is (as covered in Article 03).
🎯 Article Outline: What You'll Master
In this article, you will learn:
- ✅ The Role of
index.html
: How the main HTML file serves as the entry point. - ✅
main.jsx
Explained: The JavaScript entry point and its role in rendering the React app. - ✅
App.jsx
Deep Dive: Understanding the root React component. - ✅ The
src
Directory: A closer look at where your application code lives. - ✅ Connecting the Dots: Tracing the rendering flow from HTML to your React components.
🧠 Section 1: The Entry Points: index.html
and main.jsx
Every web application needs an entry point – a starting file that the browser loads. In a Vite React application, this process involves index.html
and main.jsx
(or main.tsx
for TypeScript projects).
1.1 - index.html
: The HTML Shell
Unlike older React setups (like Create React App) where index.html
was often tucked away in a public
folder and treated as a static asset, Vite treats index.html
as a source file and a central part of your module graph.
Open the index.html
file in your project root:
<!-- index.html -->
<!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>Vite + React</title>
</head>
<body>
<div id="root"></div> <!-- This is where your React app will be mounted! -->
<script type="module" src="/src/main.jsx"></script> <!-- Your JavaScript entry point -->
</body>
</html>
Key Observations:
<div id="root"></div>
: This is the most important line for your React application. Thisdiv
acts as the "mount point" or "root element" where your entire React application will be injected and rendered by JavaScript. When React takes control, everything inside thisdiv
will be managed by React.<script type="module" src="/src/main.jsx"></script>
: This line is the actual entry point for your JavaScript code.type="module"
: This tells the browser to treatmain.jsx
as an ES Module, allowing you to useimport
andexport
statements. Vite leverages this native browser feature for its speed.src="/src/main.jsx"
: This specifies the path to your main JavaScript file. Notice it points directly to a file inside thesrc
directory, highlighting Vite's direct serving approach.
In essence, index.html
provides the basic HTML structure and a designated spot (#root
) for your React application to live, along with the script tag that kicks off your JavaScript.
1.2 - main.jsx
: The JavaScript Orchestrator
The main.jsx
file is the JavaScript entry point that Vite loads. Its primary responsibility is to initialize your React application and "mount" it to the root
element in index.html
.
Open the src/main.jsx
file:
// src/main.jsx
import React from 'react'; // Imports the React library
import ReactDOM from 'react-dom/client'; // Imports ReactDOM for client-side rendering
import App from './App.jsx'; // Imports your main App component
import './index.css'; // Imports global CSS styles
// Create a React root and render your App component into the DOM
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<App /> {/* This is your main application component */}
</React.StrictMode>,
);
Key Lines and Their Roles:
import React from 'react';
: Imports the core React library. As discussed in Article 03, this is necessary for JSX to work.import ReactDOM from 'react-dom/client';
: ImportsReactDOM
fromreact-dom/client
.ReactDOM
is the package that provides DOM-specific methods for React.createRoot
is the modern way to create a root for your React application, replacing the olderReactDOM.render()
.import App from './App.jsx';
: This line imports your main application component,App
, fromApp.jsx
. This is where your custom UI logic will reside.import './index.css';
: This imports the global CSS file, applying styles to your entire application.ReactDOM.createRoot(document.getElementById('root'))
: This line finds thediv
element inindex.html
with the IDroot
and creates a React "root" for your application. This root is where React will manage the DOM updates..render(<React.StrictMode><App /></React.StrictMode>)
: This tells React to render yourApp
component inside the created root.<React.StrictMode>
: This is a special component that helps you find potential problems in your application during development. It activates additional checks and warnings for its descendants. It does not render any visible UI.<App />
: This is your main React component, which will render the "Hello World" content.
In summary, main.jsx
acts as the bridge between your HTML file and your React components, initiating the rendering process.
🛠️ Section 3: The src
Directory and App.jsx
The src
directory is where the heart of your React application lives. It contains all your components, styles, and assets.
3.1 - The src
Directory Structure
src/
├── assets/
│ └── react.svg # Static assets like images, SVGs
├── App.css # CSS scoped to the App component (or global if imported in App.jsx)
├── App.jsx # Your main React component
├── index.css # Global CSS styles, imported in main.jsx
└── main.jsx # The JavaScript entry point, renders App.jsx
assets/
: This folder is typically used for static assets like images, icons, or fonts that your components might use.App.css
: This file contains CSS rules specifically for theApp
component. It's imported directly intoApp.jsx
.index.css
: This file contains global CSS rules that apply to your entire application. It's imported inmain.jsx
to ensure it's loaded early.App.jsx
: This is your primary React component. When you first create a Vite React app, this file contains the default "Hello World" content.
3.2 - App.jsx
: Your Root Component
The App.jsx
file contains the App
component, which is the root of your component tree. All other components you create will typically be nested within or imported into this App
component.
Open the src/App.jsx
file:
// src/App.jsx
import { useState } from 'react'; // Import the useState Hook
import reactLogo from './assets/react.svg'; // Import an SVG asset
import viteLogo from '/vite.svg'; // Import another SVG asset (from public folder)
import './App.css'; // Import CSS specific to this component
function App() {
const [count, setCount] = useState(0); // Declare a state variable
return (
<> {/* React Fragment: allows returning multiple elements without an extra DOM node */}
<div>
<a href="https://vitejs.dev" target="_blank" rel="noopener noreferrer">
<img src={viteLogo} className="logo" alt="Vite logo" />
</a>
<a href="https://react.dev" target="_blank" rel="noopener noreferrer">
<img src={reactLogo} className="logo react" alt="React logo" />
</a>
</div>
<h1>Vite + React</h1>
<div className="card">
<button onClick={() => setCount((count) => count + 1)}>
count is {count}
</button>
<p>
Edit <code>src/App.jsx</code> and save to test HMR
</p>
</div>
<p className="read-the-docs">
Click on the Vite and React logos to learn more
</p>
</>
);
}
export default App;
Key Elements in App.jsx
:
import { useState } from 'react';
: This imports theuseState
Hook, a fundamental React feature for managing component state (which we'll cover in detail in later articles).import reactLogo from './assets/react.svg';
andimport viteLogo from '/vite.svg';
: These lines demonstrate how to import static assets (like images) into your components. Vite handles these imports efficiently. Notice the difference in paths:./assets/react.svg
is relative to the current file, while/vite.svg
refers to an asset in thepublic
folder (relative to the project root).import './App.css';
: Imports the CSS file specific to this component.function App() { ... }
: Defines the functionalApp
component.const [count, setCount] = useState(0);
: Initializes a state variablecount
with an initial value of0
.return (<> ... </>)
: The component returns JSX. The<>
and</>
are a React Fragment, which allows you to return multiple JSX elements without adding an extradiv
(or other wrapper element) to the actual DOM.- JSX Structure: The returned JSX contains various HTML elements (
div
,a
,img
,h1
,button
,p
) and displays dynamic content (count
). onClick={() => setCount((count) => count + 1)}
: This is an event handler. When the button is clicked, it calls thesetCount
function to update thecount
state, which triggers a re-render of the component.
🚀 Section 4: Tracing the Rendering Flow: From HTML to UI
Let's put it all together and trace how your "Hello World" application goes from files on your disk to a rendered UI in your browser.
- Browser Loads
index.html
: When you runnpm run dev
, Vite serves yourindex.html
file. index.html
Loadsmain.jsx
: The<script type="module" src="/src/main.jsx"></script>
tag inindex.html
tells the browser to load and executemain.jsx
as an ES Module.main.jsx
Initializes React:- It imports
React
andReactDOM
. - It imports your
App
component (import App from './App.jsx';
). ReactDOM.createRoot(document.getElementById('root')).render(<App />)
finds the#root
div inindex.html
and tells React to render theApp
component inside it.
- It imports
App.jsx
Renders UI:- The
App
component's function is executed. - It uses the
useState
Hook to manage its internalcount
state. - It returns the JSX that describes the UI (logos, heading, button, paragraph).
- The
- React's Virtual DOM in Action:
- React takes the JSX returned by
App.jsx
and builds a Virtual DOM tree. - It efficiently compares this VDOM with the previous one (if any) and calculates the minimal changes needed.
- These changes are then applied to the Real DOM in the browser.
- React takes the JSX returned by
- Browser Displays UI: The browser updates the visual display, and you see your "Vite + React" page with the interactive counter.
When you click the button, the setCount
function updates the count
state. This triggers React to re-render the App
component, create a new Virtual DOM, diff it, and apply only the change to the count
display in the Real DOM, making the UI update seamlessly.
✨ Section 5: Best Practices and Customization
Best Practices:
- Modular Components: As your application grows, break down
App.jsx
into smaller, more focused components (e.g.,Header
,Sidebar
,ProductList
). Import and compose them withinApp.jsx
. - Clear Naming: Use descriptive names for your files and components.
- Consistent Styling: Decide on a styling approach (e.g., global CSS, CSS Modules, CSS-in-JS) and stick to it.
- Understand
vite.config.js
: As your project grows, you'll likely need to customize Vite's behavior (e.g., adding plugins, setting up path aliases). Familiarize yourself withvite.config.js
.
Customization Examples:
- Changing the Title: Edit the
<title>
tag inindex.html
. - Modifying the Root Component: Change the content of
App.jsx
to build your own UI. - Adding Global Styles: Modify
index.css
or import other global stylesheets intomain.jsx
.
💡 Conclusion & Key Takeaways
You've now completed your deep dive into the structure of your first React application built with Vite! You understand the roles of index.html
, main.jsx
, and App.jsx
, and how they work together to render your UI. This foundational knowledge is critical for confidently navigating and building more complex React projects.
Let's summarize the key takeaways:
index.html
: The initial HTML shell and mount point (#root
) for your React app.main.jsx
: The JavaScript entry point that initializes React and renders your root component into the DOM.App.jsx
: Your primary React component, where you'll build and compose your application's UI.src
Directory: Contains all your application's source code, including components, styles, and assets.- Rendering Flow: Browser loads
index.html
->main.jsx
runs -> React mountsApp.jsx
to#root
-> React manages DOM updates.
Challenge Yourself:
Modify your App.jsx
file to remove the default Vite and React logos and the counter. Instead, try to render a simple "Hello, [Your Name]!" message using a new functional component that you create in a separate file (e.g., src/components/MyGreeting.jsx
) and import into App.jsx
.
➡️ Next Steps
Congratulations on completing the first series of articles! You now have a solid understanding of what React is, its core concepts, and how to set up and run your first application. In the next series, "Understanding Components", we will delve deeper into the world of React components, exploring their types, anatomy, and how to effectively use them to build modular and reusable UIs.
Thank you for your dedication. Stay curious, and happy coding!
glossary
index.html
: The main HTML file of a web application, serving as the initial page loaded by the browser. In Vite, it's also a source file.main.jsx
(ormain.tsx
): The primary JavaScript/TypeScript entry point of a React application, responsible for importing the root React component and rendering it into the DOM.App.jsx
(orApp.tsx
): The root React component of an application, typically where other components are imported and composed to build the main UI.src
Directory: The source directory in a web project where most of the application's editable code (components, styles, assets) resides.- Mount Point (or Root Element): The specific HTML DOM element (e.g.,
<div id="root"></div>
) into which a JavaScript framework (like React) injects and manages its UI. ReactDOM.createRoot()
: The modern React 18+ API for creating a root to display React components inside a browser DOM node.React.StrictMode
: A development-only tool in React that helps identify potential problems in an application by activating additional checks and warnings.- React Fragment (
<>...</>
): A feature in React that lets you group a list of children without adding extra nodes to the DOM. - Static Assets: Files (like images, fonts, or plain CSS) that are served directly by the web server without being processed or transformed by a build tool.