Create a Local React Project
By the end of this lesson, I only want one thing working properly. You'll edit a heading inside App.jsx, save the file, and see that new heading appear in your browser.
Sounds almost too small for an entire lesson, I know. But once this works, we've proved quite a lot already. Your terminal is inside the right directory, your editor has opened that same directory, Vite is serving it, and your browser is actually loading the code from there. Every lesson after this assumes all of those are connected properly, so better we confirm it now instead of finding out three lessons later that you've been editing some other App.jsx.
The directory we're creating will contain the React source code, Vite files, installed npm packages, and the scripts we'll run during development. I'm using the normal JavaScript React template here. No TypeScript for now, no extra setup, nothing else we need to discuss before getting the first screen running.
Check your tools first
Before creating a React project, we need Node.js and npm working in the terminal we're actually going to use.
And just so we're clear about what is running what: the terminal is where you're typing commands. Node.js runs JavaScript tools on your computer, npm installs packages and runs scripts, and later the browser runs the client-side JavaScript for our app. Vite itself runs through Node.js while you're developing.
So no, React isn't somehow running everything from one JavaScript process.
First check Node:
node --versionYou'll get something starting with v, maybe:
v22.14.0Your number doesn't need to match mine. For Vite 8, Node.js needs to be 20.19+ or 22.12+, or another supported release above those minimums.
And pay attention to all parts of the version number here. 20.18.0 is below 20.19, so that won't satisfy the requirement. Same with 22.11.0 when the minimum is 22.12.
Now check npm too:
npm --versionDon't expect the npm version to somehow match your Node version. They're separate programs and they have their own release numbers.
Also, run both of these commands in the same terminal you'll use for the project. Checking Node in one terminal and then opening some completely different shell to run Vite can give you a different Node installation depending on how your machine is configured.
If you get something like this:
zsh: command not found: nodethen React hasn't failed. We haven't even reached React yet.
Your shell looked for a program called node and couldn't find one. Install a supported Node.js release, then close and reopen the terminal so it picks up the new command path. After that, run node --version and npm --version again.
If you've installed Node more than once and you're not sure which copy the terminal is using, run:
which nodeOn PowerShell:
Get-Command nodeThat prints the actual executable your shell found.
This can save you from a very annoying situation where you know you installed a new Node version, node --version somehow still prints the old one, and you start questioning your life choices. Usually the shell is simply finding another installation first.
Don't create the project while your Node version is below what Vite needs. You might get partway through project creation and then fail during installation or server startup, which just gives you more files to stare at while the real problem is still Node.
Fix Node first.
Create the project
Now go to wherever you keep your code.
Mine could be:
cd ~/CodeThen check where you actually are:
pwdMaybe it prints:
/Users/reader/CodeGood. If we create reactbook-first-screen now, it'll end up at:
/Users/reader/Code/reactbook-first-screenOn PowerShell you could do:
cd C:\Code
Get-LocationUse whatever directory you normally keep source code in. I wouldn't put the project inside Downloads or some temporary folder unless you actually want it there.
Before creating anything, also make sure there isn't already a reactbook-first-screen directory containing something you care about. Don't delete an existing folder just because a project generator complained about it. Open it first and see what's inside.
Now run:
npm create vite@latest reactbook-first-screen -- --template reactThat command looks a little ugly the first time, so let's read what we're actually telling npm.
npm create vite@latest asks npm to run the currently published Vite project generator. reactbook-first-screen is the directory we want it to create. Then the standalone -- tells npm that whatever comes after should be passed through to the Vite generator. Finally, --template react tells Vite we want its JavaScript + React template.
So we're not manually installing React yet or creating files one by one. The generator creates the starter project for us.
npm might ask whether it's allowed to download create-vite. Read what it's asking to install before saying yes. Package commands can execute downloaded code on your machine, so don't get into the habit of approving random package names just because a tutorial told you to paste something.
Also, @latest only tells npm which Vite project generator to use right now. It doesn't mean your project will forever follow whatever the newest Vite release is. Once the project is generated, its own package.json and lockfile record the dependency versions selected for that project.
If everything works, Vite will print some next steps that look roughly like this:
cd reactbook-first-screen
npm install
npm run devLet's do exactly that, but one command at a time.
First:
cd reactbook-first-screenThen check the directory again:
pwdThe path should end in reactbook-first-screen.
You can also list the files:
lsOn PowerShell:
Get-ChildItemThe exact template files can change between Vite releases, so don't compare your folder against some three-year-old screenshot and panic because one SVG file has moved.
What I care about right now is that you've got the project files, including package.json, index.html, src, and Vite's config.
Now install the dependencies:
npm installnpm reads the project's package.json, figures out which package versions satisfy it, downloads them, creates node_modules, and writes or updates package-lock.json.
This command needs access to your configured npm registry unless the required packages are already available in npm's local cache.
Let the command finish and wait until your terminal prompt comes back.
You might see warnings. A warning does not automatically mean the install failed. If npm actually fails, it'll print an error and return unsuccessfully.
If that happens, don't immediately run npm install six more times hoping attempt number seven develops new abilities. Read the first useful error. Maybe npm couldn't reach the registry. Maybe there was a permission problem. Maybe one of the packages doesn't support the Node version you're running.
Fix whatever it tells you, then rerun the command.
And make sure you're running npm install inside the project directory. npm uses the package.json in your current directory as the project context, so running it from ~/Code instead of ~/Code/reactbook-first-screen is not the same thing.
One more thing: don't manually edit files inside node_modules. Those are installed package files. If something needs changing there, you're almost certainly trying to solve the problem at the wrong level.
Start the dev server
We've got a project now.
There are a bunch of generated files inside it, but don't start opening everything yet. For our first screen, the files I want you paying attention to are:
index.html
src/main.jsx
src/App.jsx
src/index.cssindex.html is the HTML document Vite serves. Somewhere in there we have the DOM container that React will use.
src/main.jsx is where the React root gets created.
src/App.jsx contains the main application component we'll edit.
And src/index.css contains the document-level styles from the starter project.
Open the whole reactbook-first-screen directory in your editor, not only App.jsx.
Opening one file directly technically lets you edit that file, sure, but now your editor doesn't have the full project context. Imports, file navigation, integrated terminals and other tooling all make much more sense when the editor has opened the project directory itself.
Now go back to the terminal, make sure you're still inside reactbook-first-screen, and run:
npm run devWhat does that command actually do?
npm opens the current package.json, finds the script called dev, and runs it. In a Vite project, that starts the Vite development server installed inside this project.
Your terminal should print a local address similar to:
Local: http://localhost:5173/Open whatever address your terminal actually prints.
Don't memorize 5173 and type it every time. If that port is already being used, Vite can start on another port instead. Maybe 5174, maybe something else. The terminal tells you where this particular server is listening.
localhost means this computer. The port number identifies which server process on this computer the browser should connect to.
So if your friend on another laptop types your http://localhost:5173/, they're asking their own machine for port 5173, not yours.
Also notice your terminal prompt hasn't come back after npm run dev.
That's normal. Vite is still running in that terminal and serving the project. Leave it running while you're working. If you need another terminal for some other command, open another one.
When you're done with the dev server, Ctrl+C stops it.
At this point you should see Vite's generated React page in the browser.
That tells us quite a few things worked already. Vite started successfully, the browser reached it, index.html loaded, the JavaScript modules loaded, and React produced something visible.
But I want one more confirmation because this is the one that catches people later.
We need to prove that the file you're editing is from the exact project Vite is serving.
Make one edit and prove the connection
Open src/App.jsx.
Delete everything inside it and replace it with:
export default function App() {
return <h1>My first React screen</h1>;
}Save the file.
Your browser should change and show:
My first React screenNo manual refresh should be needed.
Vite watches the source files in your project. Once you save App.jsx, it sees the change, processes the updated module, and sends the update to the page that's already open.
Change the heading again if you want:
export default function App() {
return <h1>Yep, this one is mine</h1>;
}Save.
If the browser changes again, good. We've now proved the editor and the running server are working on the same project.
This sounds silly until you've accidentally got two copies of a tutorial project sitting in two folders named almost the same thing. You're editing one, Vite is serving the other, and nothing changes no matter how aggressively you press Ctrl+S.
If saving App.jsx does nothing, don't restart everything immediately.
Start with the terminal. Is npm run dev still running? Is there an error printed there?
Then look at the browser URL. Does its port match the one printed by that terminal?
Now check the terminal directory:
pwdIt should point to your reactbook-first-screen project.
Then check which App.jsx your editor actually has open. The full file path should end with something similar to:
reactbook-first-screen/src/App.jsxAnd yes, make sure you actually saved it. If your editor still shows its unsaved-file indicator, Vite has no new file on disk to read yet.
Finally open src/main.jsx and confirm it imports App from the file you're editing:
import App from "./App.jsx";Go through those checks in that order and usually the problem becomes pretty obvious.
Restarting the browser, editor, terminal, Vite, Wi-Fi and probably your laptop too doesn't help much if Vite is simply serving /Code/project-a while you're editing /Code/project-b.
A running server and working source code are two different things
Keep the Vite terminal visible while you're learning.
Suppose you make a syntax mistake in App.jsx.
Maybe something simple:
export default function App() {
return <h1>Oops</h1
}The source module can't be processed correctly now.
But Vite itself may still be running.
Those two states can exist together:
dev server is running
latest source update has an errorThis is useful to understand because beginners sometimes see an error overlay in the browser and assume the entire server crashed.
It usually didn't.
Look at the browser error and the terminal output. Fix the syntax error in the source file, save again, and Vite can process the next update.
You don't reinstall Node for a missing > in JSX.
You don't run npm install again.
And please don't generate another React project because App.jsx has a syntax error. I have seen this happen more than once.
Fix the code that's actually broken.
Don't move forward until your browser shows the heading and Vite isn't reporting an active source error.
A couple of setup habits before we continue
You might come across tutorials telling you to do this:
npm install --global viteDon't do that for this project.
When we run:
npm run devnpm uses the Vite version installed for this project. That's what we want because somebody else can clone the project later, install its dependencies, and run the same project version without depending on whatever random Vite installation happens to exist globally on their machine.
The Vite project generator also works through npm, so we didn't need a permanent global Vite installation to create the project either.
You might also find older tutorials starting new projects with Create React App.
We're not using that.
Create React App is deprecated for new apps, and for this book I want the HTML entry, the React root, source files, and Vite setup sitting right there in the project where we can inspect them. We're learning what these pieces do, so hiding them would be pretty unhelpful anyway.
Before moving to the next lesson, put src/App.jsx back into this simple state if you changed the text:
export default function App() {
return <h1>My first React screen</h1>;
}Leave Vite running.
Now just verify this once with yourself: node --version satisfies what Vite 8 needs, your terminal is inside reactbook-first-screen, npm install finished successfully, npm run dev gave you a local URL, that URL opens in the browser, and saving a change inside src/App.jsx changes that same page.
If all of that works, we're done with setup.
And more importantly, you didn't just run some commands and hope React happened. You now know which directory is being served, which file you're editing, which process is still running in the terminal, and why the browser changes when you save.
That's enough setup. Next we can actually look at what Vite generated and find the point where the browser document, React DOM, and your first component connect.