Skip to content

Web & Backend

React and Next.js

React lets you describe a UI as a tree of components that re-render when their underlying state changes, rather than manually finding and updating DOM elements yourself. Next.js is a framework built on top of React that adds the pieces React alone doesn't provide: file-based routing, a choice of where and when a page is rendered (at build time, on each request, or in the browser), and a way to write backend code in the same project.

Why it matters

The component model is now the default way most teams build UI
Breaking an interface into small, reusable pieces with their own state and props has become the standard approach across most frontend work, not just React specifically.
Rendering location affects real user-facing outcomes
A page rendered only in the browser can leave users staring at a blank screen while JavaScript loads, and search engine crawlers historically struggled with content that only appears after client-side rendering.
File-based routing removes a whole category of manual setup
A file's location in the project directly determines its URL, instead of a separate routing configuration file that has to be kept in sync by hand.
It lets a team keep light backend logic in the same project as the UI
API routes or server functions mean small backend tasks (form handling, a database call) don't always need a wholly separate service.

Components, props and state

A component is a function that returns what the UI should look like for a given input. Props are the input passed down from a parent; state is data the component owns and can change over time, and changing it is what triggers React to re-render that part of the tree.

JavaScript
function OrderStatus({ orderId }) {
  const [order, setOrder] = useState(null);

  useEffect(() => {
    fetch("/api/orders/" + orderId)
      .then((r) => r.json())
      .then(setOrder);
  }, [orderId]);

  if (!order) return <p>Loading...</p>;
  return <p>Status: {order.status}</p>;
}

What Next.js adds on top of React

Plain React leaves routing, data fetching, and build tooling up to you — most non-trivial React apps end up assembling a router, a bundler, and a fetching strategy from separate pieces. Next.js bundles opinionated answers to all three: a file's path under its app or pages directory becomes its URL, pages can fetch data on the server before ever sending HTML to the browser, and small backend endpoints can live in the same project without a separate server to run.

Rendering: build time, request time, and in the browser

A page can be rendered once at build time (fine for content that rarely changes), on every request on the server (needed for content that's different per visitor or changes often), or purely in the browser after JavaScript loads (simplest, but slowest to first show anything meaningful). Picking the wrong one for a given page's data is a genuinely common source of either stale content or unnecessary slowness.

Mistakes people make here

Fetching data in useEffect when it could be fetched during rendering
A useEffect fetch only starts after the component has already rendered once, which typically means an extra loading state and a delay that server-side or render-time fetching can avoid entirely.
Mutating state directly instead of through its setter function
React doesn't detect a plain object or array mutation as a change and won't re-render, because it compares by reference — the fix is always creating a new value and passing it to the setter, not editing the existing one in place.
Making every component a client component out of habit in Next.js's app router
A component that doesn't need interactivity or browser-only APIs can usually stay a server component, sending no JavaScript for itself to the browser at all — defaulting everything to client-side ships more code than necessary.
Using an array index as a list item's key
React uses the key to track which item is which across re-renders; an index changes meaning when items are added, removed, or reordered, which can cause state to attach to the wrong item silently.

Strengths and trade-offs

Where it is strong

  • Component reuse and a very large ecosystem of supporting libraries and tooling.
  • Next.js's server rendering improves first paint and content visibility to crawlers, compared to a purely client-rendered single-page app.
  • File-based routing and built-in API routes cut down on project setup and glue code most React apps otherwise assemble by hand.
  • One language, JavaScript or TypeScript, spans the UI and any light backend logic living alongside it.

The trade-offs

  • React alone is just a UI library — routing, data fetching, and build tooling are either assembled yourself or taken on as a framework's opinions.
  • Understanding what renders where — server or client, build time or request time — is genuinely more to learn than a purely client-rendered app.
  • A large component tree with careless state updates can re-render more than necessary without deliberate memoization.
  • Adopting a framework's conventions (Next.js's routing, rendering model, deployment expectations) makes migrating away from it later a real project, not a config change.

Who needs this

Core to any frontend developer building beyond a static page; Next.js specifically matters once first-load speed, search visibility, or a combined frontend-and-light-backend project are real requirements.

Questions about react and next.js

Do I need Next.js to use React?
No — many React apps are built with just a bundler like Vite and a client-side router, with no framework layer on top. Next.js is a choice you make when its routing, rendering, and backend features solve problems you'd otherwise assemble yourself.
What does 'server component' mean in Next.js?
A component that renders on the server and sends no JavaScript of its own to the browser, as opposed to a client component, which does ship JavaScript and can use browser-only features like state and event handlers.
Is Next.js made by the same team as React?
No. React is maintained by Meta and the open-source community; Next.js is a separate framework, maintained by Vercel, built on top of React rather than being part of it.
Why would I choose Next.js over plain React?
When routing, server rendering, or an integrated backend layer would otherwise mean assembling and maintaining those pieces yourself — for a small app with none of those needs, plain React with a lightweight setup can be entirely sufficient.

The primary source

Related concepts

← All concept guides