← React for Beginners

Setting up a React project

Lesson 02 of 12 · 8 min

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.