A frontend framework is a ready-made way to build a web app's interface: it gives you structure, rules and patterns, so a page full of moving parts stays manageable. You still write the app, but the framework decides how the pieces fit together.
Why plain JavaScript gets messy
A navbar, a sidebar, a feed and a button that opens a modal sound like small features. Each one is easy alone. The trouble starts when they share state: the data that says what the page should look like right now. Is the modal open? How many unread posts are there? Who is signed in?
With plain JavaScript you keep that state in variables and update the page by hand. Every time something changes, you find the right elements and change them yourself:
const openBtn = document.querySelector('#open');
const closeBtn = document.querySelector('#close');
const modal = document.querySelector('#modal');
const badge = document.querySelector('#opens');
let opens = 0;
openBtn.addEventListener('click', () => {
opens += 1;
modal.hidden = false;
badge.textContent = opens;
});
closeBtn.addEventListener('click', () => {
modal.hidden = true;
});This works, but the code describes steps, not the result. Add a second place that shows the count, or a keyboard shortcut that also closes the modal, and you have to remember every element that depends on every variable. Miss one and the page shows something out of date. As an app grows, those hand-written updates turn into the tangle developers call spaghetti code.
What a framework gives you
A framework replaces those manual updates with a pattern. Here is the modal's open and close in React:
import { useState } from 'react';
function Modal({ onClose }) {
return (
<div role="dialog">
<p>Hello from the modal</p>
<button onClick={onClose}>Close</button>
</div>
);
}
export default function ModalButton() {
const [open, setOpen] = useState(false);
return (
<>
<button onClick={() => setOpen(true)}>
Open
</button>
{open && (
<Modal onClose={() => setOpen(false)} />
)}
</>
);
}You describe what the page should look like for a given state ('if open is true, show the modal'), and the framework works out which parts of the page to change when the state changes. This is called declarative UI, and almost every frontend framework is built on it.
The other things a framework usually brings:
- Components: reusable pieces of UI, like
Modalabove, each with its own markup, logic and state. You build a page by putting components together, and fix a bug in one place. - Predictable patterns: a set way to pass data down, handle events and fetch data, so a new developer on the team knows where to look.
- Routing: mapping URLs such as
/feedor/settingsto the right screen. - State management: ways to share state between components that are far apart on the page.
- Build tools: a development server that reloads as you save, and a build step that bundles and shrinks your code for production.
- Opinions: a preferred folder layout, naming rules and 'the right way' to do common jobs. They save you decisions, at the cost of doing things the framework's way.
Library or framework?
The difference comes down to who is in charge. You call a library when you need it. A framework calls your code: you fill in components and files in the places it expects, and it decides when they run. This idea is called inversion of control, the same 'don't call us, we'll call you' principle behind dependency injection.
By that test React is a library, and its own docs call it one: it renders components and leaves routing, data fetching and project layout to you. Most people still group it with the frameworks, because in practice you rarely use React alone.
Why there are so many
Look around and you will find React, Next.js, Remix, Gatsby, Astro and a new one every few months. Many of them build on React and add the parts React leaves out. They are sometimes called meta-frameworks: React handles the components, and the meta-framework adds routing, data loading, server rendering and a build setup. Your components look much the same in each, which is why so many of them feel React-shaped underneath.
Where they differ is mostly in three places.
Folder structure and routing
Many frameworks use file-based routing: the files and folders you create become the site's URLs. In Next.js, for example, a folder of pages maps straight to routes:
app/
page.tsx -> /
feed/
page.tsx -> /feed
settings/
page.tsx -> /settingsAstro does the same with a src/pages folder. The idea is shared; the folder names and file conventions are what change.
Where the code runs
This is where the 'server tricks' come in. A framework can produce the HTML for a page in different places:
- In the browser (client-side rendering): the server sends a nearly empty page and JavaScript builds it. Simple to host, but the first load is slower and search engines see less.
- On the server, per request (server-side rendering): the server builds the HTML for each visit, so the page arrives ready to read, then JavaScript takes over.
- At build time (static generation): pages are built once, ahead of time, and served as plain files. Very fast, and a good fit for content that rarely changes. Gatsby made its name this way.
- As islands: Astro's approach is to send plain HTML and only add JavaScript to the interactive parts, such as a search box or a carousel. Those islands can be React components, or components from other frameworks.
Branding and focus
Each one aims at a different kind of project: Next.js at full web apps, Gatsby and Astro at content-heavy sites such as blogs and docs, Remix at apps built around forms and server data. The overlap is large, and much of the choice comes down to the team's taste and what they already know.
React is not the only base, either. Vue and Svelte have their own meta-frameworks, Nuxt and SvelteKit, and Angular is a full framework on its own. Each has its own component model, but they share the same core idea: components that render from state.
When to use one
A framework earns its place when the interface has a lot of state that changes while the user is on the page: dashboards, editors, feeds, anything that feels like an app. It also helps on a team, where shared patterns matter more than any one person's preferences.
It is often more than you need for a mostly static page, such as a landing page or a simple blog. Plain HTML, CSS and a little JavaScript load faster and have nothing to upgrade. If you want components without shipping much JavaScript, an islands-style framework sits in between.
Common mistakes
- Learning the framework before the language: frameworks change, but JavaScript, HTML and CSS stay. If you understand events, the DOM and how a browser loads a page, every framework is easier to pick up.
- Fighting the framework's opinions: putting files in your own layout or updating the page by hand around the framework usually breaks its routing or its updates. If its opinions don't suit the project, choose a different one.
- Choosing by hype: a framework that launched last month has fewer answers online and may change under you. A widely used one is usually the safer pick for a first project.
- Keeping too much state: storing values you could work out from other state means two copies that can disagree, which is the bug the framework was meant to prevent.
Key takeaways
- A frontend framework gives structure, rules and patterns; you write the app, it decides how the pieces fit together.
- The core idea is declarative UI: describe the page for a given state, and the framework keeps the page in step.
- Components make UI reusable, and routing, state management and build tools usually come with them.
- Many popular frameworks are React underneath, differing in folder structure, where the code runs and what they aim at.
- Learn the web platform first, then pick the framework that fits the project.