Throughout this track you have run React straight in the browser with Babel. That is perfect for learning, but it is not how real apps are built. In this final lesson you will create a proper React project with Vite, a fast build tool, on your own computer, and see how the code you already know fits into separate files.
Why use a build tool?
A build tool does the heavy work before your site reaches visitors instead of in their browser. With Vite you get:
- JSX compiled ahead of time, so visitors download plain, small JavaScript – no Babel in the page.
- A development server that updates the page instantly when you save a file, often keeping the component’s state (Fast Refresh).
- npm packages: you install React and other libraries with
npmand import them by name, e.g.import { useState } from "react". - A production build that bundles, minifies and fingerprints your files for fast loading and caching.
Watch out: Old tutorials use create-react-app. The React team deprecated it for new apps in February 2025. Do not start new projects with it; use Vite, as shown here, or a framework.
Step 1: Install Node.js
Vite runs on Node.js, which also gives you npm, the package manager. Install the current LTS version from the official Node.js website. Vite needs Node.js 20.19 or newer (or 22.12 or newer on the 22 line). Check your version in a terminal with node -v. You will also want a code editor such as VS Code.
Step 2: Create a React project with Vite
Open a terminal in the folder where you keep your projects and run the commands below. The --template react option picks the plain JavaScript React template; react-ts would give you TypeScript instead. Depending on the version, create-vite may ask a question or two – read each prompt and accept the defaults if you are unsure.
npm create vite@latest my-react-app -- --template react
cd my-react-app
npm install
npm run devThe extra -- passes the --template option through npm to create-vite. When the dev server starts, it prints a local address, normally http://localhost:5173. Open it in your browser and you will see the starter page. Leave the terminal running while you work; press Ctrl + C to stop the server.
Step 3: Understand the files
| File or folder | What it is for |
|---|---|
index.html | The single HTML page. In Vite it sits in the project root and loads /src/main.jsx. |
src/main.jsx | The entry point. It calls createRoot and renders <App /> – the same job as the last lines of our browser examples. |
src/App.jsx | The top-level component. Start editing here. |
src/*.css | Stylesheets imported straight into JavaScript files. |
public/ | Files copied as they are, such as a favicon. |
package.json | Project name, dependencies (react, react-dom) and the dev, build and preview scripts. |
node_modules/ | Installed packages. Never edit or upload it; npm install recreates it. |
vite.config.js | Vite settings, including the React plugin. |
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import "./index.css";
import App from "./App.jsx";
createRoot(document.getElementById("root")).render(
<StrictMode>
<App />
</StrictMode>
);Two differences from our browser examples stand out. Imports use bare package names ("react") instead of CDN URLs, and you do not need import React, because Vite uses the modern JSX transform that adds what it needs automatically. StrictMode turns on extra development-only checks, such as the double effect run you read about in React useEffect.
Step 4: Components in their own files
In a real project, each component usually gets its own file, named after the component. A file shares its component with export default, and other files load it with import. Here is a small tea-stall menu split into two files:
// src/MenuItem.jsx
export default function MenuItem({ name, price, onAdd }) {
return (
<li>
{name} – ₹{price}{" "}
<button type="button" onClick={() => onAdd(price)}>Add</button>
</li>
);
}
// src/App.jsx
import { useState } from "react";
import MenuItem from "./MenuItem.jsx";
import "./App.css";
const menu = [
{ id: 1, name: "Masala chai", price: 20 },
{ id: 2, name: "Filter coffee", price: 25 },
{ id: 3, name: "Bun butter jam", price: 40 }
];
export default function App() {
const [total, setTotal] = useState(0);
return (
<main>
<h1>Tea stall</h1>
<ul>
{menu.map(item => (
<MenuItem key={item.id} name={item.name} price={item.price}
onAdd={price => setTotal(t => t + price)} />
))}
</ul>
<p>Total: ₹{total}</p>
</main>
);
}Save both files and the browser updates at once. Here is the same app in the learning setup, so you can try it on this page before building it on your computer:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>The tea stall app in the learning setup</title>
<script src="https://unpkg.com/@babel/[email protected]/babel.min.js"></script>
<style>
body { font-family: system-ui, sans-serif; padding: 16px; line-height: 1.5; }
li { margin-bottom: 6px; }
</style>
</head>
<body>
<div id="root"></div>
<script type="text/babel" data-type="module">
import React, { useState } from "https://esm.sh/[email protected]";
import { createRoot } from "https://esm.sh/[email protected]/client";
function MenuItem({ name, price, onAdd }) {
return (
<li>
{name} – ₹{price}{" "}
<button type="button" onClick={() => onAdd(price)}>Add</button>
</li>
);
}
const menu = [
{ id: 1, name: "Masala chai", price: 20 },
{ id: 2, name: "Filter coffee", price: 25 },
{ id: 3, name: "Bun butter jam", price: 40 }
];
function App() {
const [total, setTotal] = useState(0);
return (
<main>
<h1>Tea stall</h1>
<ul>
{menu.map(item => (
<MenuItem key={item.id} name={item.name} price={item.price}
onAdd={price => setTotal(t => t + price)} />
))}
</ul>
<p>Total: ₹{total}</p>
</main>
);
}
createRoot(document.getElementById("root")).render(<App />);
</script>
</body>
</html>Step 5: Build and preview
When you are ready to publish, run npm run build. Vite writes an optimised version of your app into a dist folder. Run npm run preview to test that build locally before you upload it. The dist folder is a set of static files – HTML, CSS and JavaScript – that any static web host can serve.
Where to go next
A React project with Vite is a single-page app: one HTML page whose content React changes. For multiple pages with their own URLs, server rendering or full-stack features, the React team points to frameworks built on React, such as Next.js and React Router. You do not need one to keep learning – practise first by building small Vite projects: a to-do list, a quiz, or a weather card that fetches data. When you are preparing for jobs, React Interview Questions and the Front-End Developer Roadmap will help you plan.
