Topic 0.4
Your First React App
In one line
A React app starts by creating a root on one HTML element with createRoot and rendering your top component into it; a real project gets the same setup from Vite in one command.
Think of it like this
A picture frame on a wall. The wall is your HTML page, the empty frame is one <div id="root">, and React paints everything inside the frame. The rest of the wall stays plain HTML. You hang the frame once (createRoot) and then tell React what picture to show (render).
Words you'll meet
New words in this topic, in plain English. Come back here whenever one feels fuzzy.
- react
- The core package: components, hooks and rendering logic, with no knowledge of the browser.
- react-dom
- The package that puts React output into a web page (the DOM).
- Root container
- The one HTML element React takes control of, usually
<div id="root">. - createRoot
- The function that sets up React inside a root container:
createRoot(element). - render (root.render)
- Tells React which component tree to show in the root.
- StrictMode
- A development-only wrapper that runs some code twice to reveal hidden bugs.
- Vite
- A fast build tool that creates React projects, runs a dev server and builds them for production.
- Compile
- Turn code into another form the browser can run, such as JSX into plain JavaScript.
Step by step
01The page has one empty element
React needs somewhere to draw. The HTML page has a single empty div, usually with id="root".
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>02Write your top component
App is an ordinary function that returns JSX. Its name starts with a capital letter.
export default function App() {
return <h1>Hello, React!</h1>;
}03Create the root and render
In the entry file, find the root element, hand it to createRoot, and render App into it. This file runs once when the page loads.
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import App from "./App.jsx";
createRoot(document.getElementById("root")).render(
<StrictMode>
<App />
</StrictMode>,
);04Make a real project with Vite
In a terminal, create a project, install its packages and start the dev server. Open the address it prints (usually http://localhost:5173). Edit src/App.jsx, save, and the browser updates instantly.
$ npm create vite@latest my-app -- --template react
◇ Scaffolding project in /home/asha/my-app...
└ Done. Now run:
cd my-app
npm install
npm run dev
$ cd my-app && npm install && npm run dev
VITE v8.3.3 ready in 621 ms
➜ Local: http://localhost:5173/
➜ Network: use --host to expose05Know the files Vite made
index.html holds the root div. src/main.jsx creates the root. src/App.jsx is your first component, with App.css and index.css for styles. package.json lists react and react-dom and the scripts dev, build, lint and preview. public/ holds files served as they are (like the favicon).
06Build for production
npm run build compiles and minifies everything into dist/. Those files are what you upload to a host (Phase 23). Hashes in the file names let browsers cache them safely.
$ npm run build
> my-app@0.0.0 build
> vite build
vite v8.3.3 building client environment for production...
transforming...
✓ 20 modules transformed.
rendering chunks...
computing gzip size...
dist/index.html 0.45 kB │ gzip: 0.29 kB
dist/assets/index-DykytF2W.css 4.10 kB │ gzip: 1.47 kB
dist/assets/index-CyBHeG3D.js 222.52 kB │ gzip: 69.26 kB
✓ built in 314msTry it yourself
- 1
Make it yours
In "Hello, React!", change the heading to your name and add a second paragraph saying what you want to build.
- 2
Remove StrictMode
In the StrictMode example, render
<App />without the<StrictMode>wrapper. Predict the console, then run it. (One render, and the count is 1.) - 3
Two roots on one page
In the second example, add
<div id="second"></div>to the HTML and a second line:createRoot(document.getElementById("second")).render(<App />);. React now manages two separate areas of the page.
Code & diagrams
The three steps: find the container, create a root, render App into it.
Preview
Console
Nothing logged yet.React owns only the inside of its root. The content that was there is replaced; the rest of the page is untouched. A loading message inside the root is a common trick for slow connections.
Preview
Console
Nothing logged yet.Expected console output
Before render: Loading… (this text is replaced by React)
After render: This paragraph comes from React.In development, StrictMode calls your component twice to catch code that changes things while rendering (like `renders` here). A production build calls it once. You'll learn why this helps in Topic 2.6.
Preview
Console
Nothing logged yet.Expected console output
App rendered
App rendered
render count: 2Break it on purpose
Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.
Break #1
Point createRoot at an element that doesn't exist
In "Hello, React!", change getElementById("root") to getElementById("app").
Break #2
Call render with a lowercase function
Rename App to app and render <app />.
Myth vs fact
Myth
You call render every time something changes.
Fact
You call root.render once. After that, components update themselves when their state changes.
Myth
StrictMode makes the production app slower.
Fact
StrictMode's double calls happen only in development. In a production build, <StrictMode> does nothing.
Myth
React apps need a server to run.
Fact
A Vite build is plain static files (HTML, JS, CSS). Any static host can serve them. Servers matter for server rendering and APIs (Phase 20).
Pro corner
Extra depth for experienced readers. New to this? Skip it for now and come back later.
- ▸
createRootreplacedReactDOM.renderin React 18 and enables concurrent features.ReactDOM.renderwas removed in React 19, so old tutorials that use it won't work with current React. - ▸
createRoottakes options:onUncaughtError,onCaughtErrorandonRecoverableError(React 19) let you send render errors to your error-reporting service (Topic 14.5 and Phase 23.5).hydrateRootis the server-rendering counterpart (Topic 20.6). - ▸
root.unmount()removes the React tree and runs all cleanups: useful when you embed a React widget inside a non-React app and need to tear it down. - ▸
Vite serves your source files as native ES modules in development (fast start, instant updates) and bundles them for production. You'll see what the build does step by step in Topic 23.1.
Remember this
- 1
Every React web app needs two packages: **
react(components, hooks and the rendering logic) andreact-dom** (the part that knows how to put React elements into a browser page).createRootcomes fromreact-dom/client. - 2
createRoot(domElement)takes over one DOM element, called the root container. Anything already inside it is replaced.root.render(<App />)tells React what to show there. You normally callrenderonce; after that, changes happen through state inside your components, not by callingrenderagain. - 3
Your top component is usually called
App. It's a function that returns JSX, the HTML-like syntax you'll study in Phase 1. JSX must be compiled (turned into plain JavaScript) before a browser can run it. On Hectal the live editor compiles it for you; in a project, a build tool such as Vite does it. - 4
StrictMode (
<StrictMode><App /></StrictMode>) is a development helper. It doesn't show anything. It makes React render your components twice and run setup code for effects twice, to expose bugs that come from impure code (Topic 2.6 and Topic 7.4). It only does this in development; production builds run everything once. New projects wrap the app in StrictMode by default. Hectal's examples leave it out so eachconsole.logprints once, unless the lesson is about StrictMode. - 5
Vite is the usual tool to start a React project.
npm create vite@latestmakes a folder with anindex.html(containing the rootdiv), asrc/main.jsx(which callscreateRoot), and ansrc/App.jsx.npm run devstarts a development server that reloads the page as you save (hot module replacement), andnpm run buildproduces small optimised files indist/to put on a web server (Phase 23). - 6
Can React control just part of a page? Yes. Because React only manages the inside of its root, you can add React to one widget of an existing site, or have several roots on one page. Whole apps usually have a single root.
Explain it without notes
What do react and react-dom each do?
Walk through the code that starts a React app, line by line.
What does StrictMode do, when, and why would you want it?
What do npm run dev and npm run build do in a Vite project?
Practice
Write the full main.jsx for an app whose root element has the id app and whose top component is Shop from ./Shop.jsx, using StrictMode.
Make a live component that shows a heading My first React app and a paragraph with today's lesson number, 0.4.
Trade-offs
- ↔
Vite is the simplest start for a client-only app. If you need server rendering, file-based routing or server components from day one, start with a framework such as Next.js instead (Phase 20).
- ↔
StrictMode's double calls make development logs noisier, but they catch real bugs early; keep it on.
Done when you can
I can write the three lines that start a React app.
I know what
react,react-domandcreateRootare for.I can explain what StrictMode does and that it is development-only.
I can create, run and build a project with Vite.
I know which file does what in a new Vite project.