What is React?
React is a JavaScript library for building user interfaces out of small, reusable pieces called components. Created and maintained by Meta and open-sourced in 2013, it has become the most widely used way to build interactive web apps. Instead of manually reaching into the page to update text, toggle classes, and insert elements, you describe what the UI should look like for a given state, and React figures out the changes needed to get there. This page introduces what React is, the ideas behind it, and where it runs — the foundation for everything else in these docs.
A library, not a framework
React deliberately does one thing well: render UI. It does not dictate how you fetch data, route between pages, manage global state, or style your app. Those choices are left to you and the surrounding ecosystem — libraries like React Router, TanStack Query, or full frameworks like Next.js built on top of React.
That focus is why React is best described as a library rather than a framework. A framework calls your code inside its own structure; React is a tool you call to produce and update views. The trade-off is freedom with responsibility: you assemble the pieces you need, which keeps React small and composable but means a real app combines several packages.
Components: the core idea
A component is a function that returns a description of some UI. You compose components together — a Page made of a Header, a Sidebar, and a Feed of Posts — the same way you compose functions. Each component owns its own markup and logic, so you build and reason about the interface one self-contained unit at a time.
Components are written in JSX, a syntax extension that lets you write markup directly inside JavaScript. Here is a complete first component:
function Greeting({ name }) {
return <h1>Hello, {name}!</h1>;
}
export default function App() {
return (
<main>
<Greeting name="Ada" />
<Greeting name="Linus" />
</main>
);
}
Greeting accepts props (inputs passed from a parent) and returns JSX. App uses it twice with different props. The curly braces in JSX embed any JavaScript expression — here the name value — directly into the output.
Note: Modern React is written with function components and hooks. Class components still work and appear in older code, but every new component you write should be a function.
Declarative vs imperative UI
The shift React asks you to make is from imperative to declarative code. Imperative code lists the steps to mutate the DOM by hand; declarative code states the desired result and lets React perform the steps.
// Imperative — you manage every DOM operation
const button = document.querySelector("#like");
let liked = false;
button.addEventListener("click", () => {
liked = !liked;
button.textContent = liked ? "Liked" : "Like";
button.classList.toggle("active", liked);
});
// Declarative — you describe the UI for the current state
import { useState } from "react";
function LikeButton() {
const [liked, setLiked] = useState(false);
return (
<button className={liked ? "active" : ""} onClick={() => setLiked(!liked)}>
{liked ? "Liked" : "Like"}
</button>
);
}
In the React version you never touch the DOM. You hold the liked state, render what the button should look like for that state, and call setLiked to change it. React re-renders and updates the screen for you.
The virtual DOM at a glance
How does React update the page efficiently without you writing DOM code? When state changes, React re-runs your component and produces a fresh, lightweight in-memory description of the UI — the virtual DOM. It then compares that new tree to the previous one (a process called reconciliation) and applies only the minimal set of real DOM changes that differ.
This means you can re-render freely after every state change and trust React to keep the actual page updates small and fast — you get the simplicity of “redraw everything” with the performance of targeted edits.
state change → new virtual tree → diff vs. old tree → patch only what changed
Where React runs
React itself is just the component model and reconciler; a separate renderer turns components into something concrete. This split is what lets the same mental model target very different platforms.
| Target | Renderer | What it produces |
|---|---|---|
| Web browsers | react-dom | HTML DOM nodes |
| Server-rendered web | react-dom/server | HTML strings / streams |
| Native mobile apps | React Native | Real iOS and Android views |
| Other surfaces | custom renderers | Canvas, terminals, PDFs, etc. |
For web apps you pair React with react-dom, usually scaffolded with Vite. For iOS and Android you use React Native, which renders to genuine native widgets rather than a web view.
What you can build
Because React scales from a single interactive widget to an entire application, it powers a wide range of products:
- Single-page applications — dashboards, editors, and admin panels with rich client-side interactivity.
- Server-rendered and static sites — fast, SEO-friendly pages via frameworks like Next.js or Remix.
- Mobile apps — cross-platform iOS/Android apps with React Native.
- Embedded widgets — a checkout, chat, or comments component dropped into an existing site.
- Design systems — shared component libraries reused across many products.
Best practices
- Build UIs from small, focused components and compose them, rather than writing large monolithic ones.
- Think declaratively: describe the UI for each state and let React update the DOM — avoid manual DOM manipulation.
- Use function components and hooks for all new code; reserve class components for understanding legacy projects.
- Keep components pure where you can — given the same props and state, they should render the same output.
- Lift state to the closest common ancestor that needs it, and pass data down through props.
- Start with React plus a build tool like Vite, then add ecosystem libraries (routing, data fetching) only as the app requires them.