React is not something you drop into a page with a script tag and get on with. It needs a
build step, because the JSX from the last lesson - the HTML-looking syntax inside
JavaScript - is not JavaScript, and no browser can run it. Something has to translate it
first.
You do not have to assemble that yourself. One command produces a working project.
One command
First you need Node.js, which is JavaScript running outside the browser. The build tooling
runs on it. Open a terminal and check:
node --version
If that prints v22.12 or higher you are set. If it prints something older, or errors, get
the LTS build from nodejs.org and run it again. Node 20.19 and above
also works, but if you are installing fresh take the current LTS. npm comes with Node,
so there is nothing else to install.
Then:
npm create vite@latest
Vite (rhymes with “sweet”) is a build tool. It translates your JSX, serves your files
while you work, and bundles everything for production. React itself does none of that.
The command asks you five things:
- Project name -
react-practice will do.
- Framework - React.
- Variant - JavaScript. You will see TypeScript options too; ignore them for now.
TypeScript is worth learning and it is not worth learning at the same time as React.
- Which linter to use? - Oxlint or ESLint. A linter flags suspect code; this course
never runs it, so either is fine. Take Oxlint, the first option, and the file tour below
will match what you have.
- Install with npm and start now? - say no. It saves you two commands and hides
what they do, and those two commands are worth the thirty seconds. If you said yes
anyway, everything is installed and the server is already running - skip the block below
and open the URL it printed.
Then follow the three lines it prints:
cd react-practice
npm install
npm run dev
npm install downloads React and Vite into the project. npm run dev starts a local
server and prints a URL - usually http://localhost:5173. Open it and you have a running
React app.
Leave that command running. It watches your files, and when you save one it updates the
page in the browser almost instantly, usually without even reloading it. That is the whole
reason the dev server exists. It is also the loop you will spend the rest of this course
in: edit, save, look.
If you find a tutorial that tells you to run create-react-app, close it. That tool was
the standard for years and was retired in 2025; React’s own documentation no longer
recommends it. Anything built on it is old enough that its React advice will be old too.
What just got created
More files than you need, which is normal and unhelpful.
You will edit these:
src/App.jsx - a component. Right now it is a hundred-line demo: a counter, three
images, and a panel of links to documentation and social accounts. All of it is going in
a minute. This is where you will work for the next few lessons.
src/main.jsx - the handful of lines that connect React to the page. You will look at
this once, understand it, and rarely open it again.
index.html - the actual HTML page. Nearly empty, on purpose.
You will edit these occasionally:
src/index.css and src/App.css - plain CSS files. No React-specific styling system is
involved; these are stylesheets.
package.json - the project’s manifest: its name, its dependencies, and the commands
you can run.
public/ - files served exactly as they are, at the root of the site. Here, a
favicon.svg and an icons.svg sprite the demo uses.
You can ignore these entirely:
node_modules/ - the downloaded dependencies. Thousands of files. Never edit anything
in here, never commit it, and delete it without ceremony if things get strange -
npm install puts it back.
vite.config.js - build configuration. The default is correct for now.
.oxlintrc.json - settings for the linter you picked at that prompt. Useful later,
irrelevant today. Pick ESLint instead and this file is eslint.config.js.
.gitignore, README.md, and src/assets/ - housekeeping, plus the images the demo
uses.
If your folder does not match this exactly, that is fine and expected: the template gets
revised, and which linter it ships has changed more than once. The three files that matter
index.html, src/main.jsx, src/App.jsx - have been the same for years.
How the page and the JavaScript meet
Two files, and then the whole thing makes sense. Open index.html:
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
That is the interesting half of it: an empty div and a script. Everything you see in the
browser gets put inside that div by React - which means if you ever load the page with
JavaScript disabled, you get a blank screen. That is the deal with this kind of app.
Now src/main.jsx:
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>,
)
Read it as English: find the element with id="root", make it a React root, and render
the App component inside it. That is the entire connection between React and the page,
and you will not need to change it.
import and export are how JavaScript files share code. App.jsx ends with
export default App, which means “this file’s main thing is App”; import App from "./App.jsx" picks it up at the other end. The braces in import { StrictMode } from "react" mean the opposite direction - take the specifically-named StrictMode out of a
package that exports several things. You will write both forms constantly.
StrictMode is a wrapper that turns on extra checks while you are developing. It does
nothing in the built version of your site. Leave it exactly where it is; in lesson 10 it
does something surprising and you will want it there when that happens.
Clear out the demo
Replace the whole of src/App.jsx with this:
function App() {
return <h1>Hello from React</h1>;
}
export default App;
Note what went with it: a few lines down from the top the demo had import './App.css',
and deleting that line is what unloads the stylesheet. A CSS file in a React project does
nothing until something imports it. You can leave App.css sitting there, empty or not.
src/index.css is a different matter, because main.jsx imports it and you are not
touching main.jsx. It is over a hundred lines of the template’s own design - a base
font, a colour palette, and a color-scheme: light dark rule that will flip your page to
white-on-black if your system is in dark mode. Open it, select all, delete: the file needs
to be completely empty, or you will spend the next few lessons wondering why your unstyled
heading is styled.
Save and look: a plain heading in the browser’s default font, and nothing else.
Unstyled is the correct look here - this course is about React, and the sooner nothing on
screen is unexplained the better.
That is a React app: a function that returns some markup, connected to a div in an
otherwise empty HTML file. Everything from here is that same idea, elaborated.
The commands you have
package.json lists them under "scripts", and you run any of them with npm run:
npm run dev - the development server. The one you will use.
npm run build - produces a dist/ folder of plain HTML, CSS and JavaScript, ready to
upload anywhere. This is the only version a real visitor ever sees.
npm run preview - serves that dist/ folder locally, so you can check the built
version behaves like the development one.
npm run lint - runs the linter you chose when you created the project.
You need the first one. The others will matter eventually.
Recap
A React project is a folder with a build tool in it. npm create vite@latest sets one up,
npm run dev starts it, and of everything it generated only src/App.jsx matters today.
The chain is short: index.html has an empty div, main.jsx renders App into it, and
App is a function that returns markup.
Next: that markup. What JSX actually is, the handful of rules it has, and how to write
components of your own.