The live editors in this course are perfect for learning, but real React apps live in a project on your computer: many files, a build tool and a development server. This lesson creates one. Nothing here is hard, but every step has to work, so go slowly and read any error message. You will need a terminal and a code editor such as Visual Studio Code.
What a build tool does
Browsers cannot read JSX directly, and a real app has dozens of files and packages. A build tool compiles JSX into plain JavaScript, joins your files and the libraries you use, and during development serves the result and refreshes the browser when you save. The tool this course uses is Vite (pronounced "veet", French for "fast"). It is the standard choice for new React projects. Older tutorials use Create React App, which the React team has deprecated, so do not follow those setup steps.
If you later want routing, server rendering and file-based pages in one package, frameworks such as Next.js are built on React and include a build tool. Starting with plain React and Vite lets you learn React itself first, which transfers to any of them.
Step 1: install Node.js
Vite and npm run on Node.js. Install the current LTS version from nodejs.org, then check it in a terminal:
node --version
npm --versionYou should see version numbers, for example v26.8.1 and 11.19.0 (yours will differ). Vite needs Node.js 20.19 or newer, or 22.12 or newer; a recent LTS release is fine. npm is Node's package manager, installed with it. It downloads libraries from the npm registry into a node_modules folder.
Step 2: create the project
In a terminal, go to the folder where you keep projects and run:
npm create vite@latest my-app -- --template reactmy-app is the folder name; choose your own (no spaces). The --template react option picks the plain React template. If you leave it out, the command asks questions: choose React, then JavaScript. This course uses JavaScript to keep the focus on React; TypeScript is a good next step later. The command finishes with:
Scaffolding project in .../my-app...
Done. Now run:
cd my-app
npm install
npm run dev(The exact wording changes between versions of the tool.) Do what it says:
cd my-app
npm installnpm install reads package.json and downloads React, Vite and the other packages into node_modules. It takes from a few seconds to a minute and prints a summary such as found 0 vulnerabilities. You only need to run it again when package.json changes.
Step 3: start the development server
npm run dev VITE v8.3.5 ready in 96 ms
➜ Local: http://localhost:5173/
➜ Network: use --host to exposeOpen the Local address in your browser. You will see the starter page with a "Count is 0" button. (The port is usually 5173; if it is busy, Vite picks the next number and tells you.) Leave this terminal running. Press Ctrl+C in it to stop the server.
Step 4: change something
Open the project folder in your code editor and open src/App.jsx. Replace its contents with a tiny component:
import { useState } from "react";
function App() {
const [count, setCount] = useState(0);
return (
<div>
<h1>My first React app</h1>
<p>Hello from React 19.</p>
<button onClick={() => setCount(count + 1)}>Count is {count}</button>
</div>
);
}
export default App;My first React app
Hello from React 19.
Count is 1Save the file. The browser updates by itself, without you reloading, usually keeping the count you had clicked. This is hot module replacement (HMR): Vite sends only the changed module to the page. Try editing the heading text and saving. If you make a mistake, the browser shows an error overlay with the file and line; fix it, save, and the page recovers.
The code above is the same kind of file the lesson editors run, which is why you can copy any example from this course into src/App.jsx and it will work (for examples that use more than one file, create the extra files next to it).
Step 5: build for production
The development server is for you. To produce files for a real website:
npm run buildvite v8.3.5 building client environment for production...
✓ 20 modules transformed.
dist/index.html 0.45 kB │ gzip: 0.29 kB
dist/assets/react-CHdo91hT.svg 4.12 kB │ gzip: 2.06 kB
dist/assets/vite-BF8QNONU.svg 8.70 kB │ gzip: 1.60 kB
dist/assets/hero-CLDdwZDr.png 13.05 kB
dist/assets/index-DykytF2W.css 4.10 kB │ gzip: 1.47 kB
dist/assets/index-DSXtc1GT.js 222.44 kB │ gzip: 69.28 kB
✓ built in 71ms(A few progress lines such as "transforming..." are left out.) The dist folder now holds a complete static website: index.html, one JavaScript file, one CSS file and the images. The file names include a hash of their content (index-DSXtc1GT.js) so browsers can cache them for a long time and still pick up new versions. The React part is about 70 kB after gzip compression. To check the production build locally before uploading, run npm run preview; it prints Local: http://localhost:4173/ by default. A later lesson covers building and deploying in more detail.
The scripts in package.json
The template's package.json defines four scripts, which you run with npm run <name>:
| Script | What it does |
|---|---|
dev |
starts the development server with hot reloading |
build |
creates the optimised production files in dist |
preview |
serves the contents of dist so you can test the production build |
lint |
checks the code for common problems with Oxlint |
npm run lint on the fresh template prints nothing but the command line, which means no problems. Linting catches mistakes such as breaking the rules of hooks, a topic for later lessons.
When things go wrong
command not found: npm: Node.js is not installed, or the terminal was opened before the installation. Reopen the terminal.- The version is too old: update Node.js;
node --versionmust meet Vite's requirement. npm installfails with network errors: check your connection or proxy, then run it again.- The page is blank: open the browser console (F12) and read the first red error. A typo in JSX is the usual cause.
Port 5173 is in use: Vite will use another port; use the address it prints.- You edited a file but nothing changed: make sure you saved, and that you are editing the project the server is running.
Common mistakes
- Running the commands outside the project folder. Run
npm run devinsidemy-app, wherepackage.jsonis. - Skipping
npm install, which causes "cannot find package" errors. - Closing the terminal and expecting the site to keep running; the dev server only runs while the command runs.
- Uploading the
srcfolder to a web host. Upload the contents ofdist. - Committing
node_modulesto Git. The template's.gitignorealready excludes it. - Following an old tutorial that uses
npx create-react-app.
Exercise
- Create a project called
practicewith the commands above and start the dev server. - Change
src/App.jsxso it shows your name in anh1and a button that counts clicks. - Run
npm run buildand look insidedist. How big is the JavaScript file? - Run
npm run preview, open the address, and confirm it looks the same as the dev version.
Key points
- Vite is the build tool most React projects use today; it starts instantly and reloads the page as you edit.
- npm create vite@latest my-app -- --template react creates the project, npm install adds the packages, npm run dev starts the server.
- You need Node.js 20.19 or newer (or 22.12 or newer) installed; check with node --version.
- npm run build creates optimised files in the dist folder, which is what you upload to a web host.