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
importandexportstatements 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.jsxExplained: The JavaScript entry point and its role in rendering the React app. - ✅
App.jsxDeep Dive: Understanding the root React component. - ✅ The
srcDirectory: 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. Thisdivacts 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 thisdivwill 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.jsxas an ES Module, allowing you to useimportandexportstatements. 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 thesrcdirectory, 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';: ImportsReactDOMfromreact-dom/client.ReactDOMis the package that provides DOM-specific methods for React.createRootis 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 thedivelement inindex.htmlwith the IDrootand 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 yourAppcomponent 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 theAppcomponent. It's imported directly intoApp.jsx.index.css: This file contains global CSS rules that apply to your entire application. It's imported inmain.jsxto 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 theuseStateHook, 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.svgis relative to the current file, while/vite.svgrefers to an asset in thepublicfolder (relative to the project root).import './App.css';: Imports the CSS file specific to this component.function App() { ... }: Defines the functionalAppcomponent.const [count, setCount] = useState(0);: Initializes a state variablecountwith 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 thesetCountfunction to update thecountstate, 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.htmlfile. index.htmlLoadsmain.jsx: The<script type="module" src="/src/main.jsx"></script>tag inindex.htmltells the browser to load and executemain.jsxas an ES Module.main.jsxInitializes React:- It imports
ReactandReactDOM. - It imports your
Appcomponent (import App from './App.jsx';). ReactDOM.createRoot(document.getElementById('root')).render(<App />)finds the#rootdiv inindex.htmland tells React to render theAppcomponent inside it.
- It imports
App.jsxRenders UI:- The
Appcomponent's function is executed. - It uses the
useStateHook to manage its internalcountstate. - 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.jsxand 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.jsxinto 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.jsxto build your own UI. - Adding Global Styles: Modify
index.cssor 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.srcDirectory: Contains all your application's source code, including components, styles, and assets.- Rendering Flow: Browser loads
index.html->main.jsxruns -> React mountsApp.jsxto#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.srcDirectory: 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.