All posts

The Modern Web Stack

By Scott Rippey

Spend ten minutes around modern web development and the vocabulary starts piling up: TypeScript, React, Next.js, Tailwind, Node, Vercel. Each one sounds like another thing you are supposed to already understand, and together they can make building a web app feel like it needs a computer science degree just to get started.

It does not. Here is the part the jargon hides: underneath every one of those names, a modern web app is still just JavaScript and CSS running in a browser. Everything else is tooling - layers stacked on top of that simple core to help you build faster, with fewer bugs, and with less to maintain. Once you can see what each layer actually does, the whole stack stops being intimidating and starts looking like what it is: a set of tools, each with one job.

So let's walk up the stack one layer at a time.

The stack at a glance

Before we build it up, here is the whole cast and what each part is actually for:

LayerWhat it isIts one job
JavaScriptThe language browsers runMake the page interactive
TypeScriptJavaScript with a safety netCatch mistakes before they ship
ReactA JavaScript UI libraryBuild the interface from reusable pieces
TailwindA CSS toolkitStyle everything, quickly
Next.jsA React frameworkAdd routing, server rendering, and a backend
Node.jsA JavaScript runtimeRun all of it outside the browser

Every row is either JavaScript or CSS wearing a different hat. Hold onto that and the rest is just detail.

Diagram of the modern web stack: JavaScript at the foundation, then TypeScript, React, and Next.js, with Tailwind and CSS alongside, all compiling down to the HTML, CSS, and JavaScript a browser runs.

The three languages a browser actually speaks

Strip a web page down to the metal and a browser only really understands three things:

  • HTML gives the page its structure - the headings, paragraphs, buttons, and boxes that exist on the page.
  • CSS controls how all of that looks - colors, spacing, fonts, layout, animation.
  • JavaScript makes it do something - respond to a click, load new data, update what is on screen without reloading the page.

HTML and CSS describe the page. JavaScript brings it to life. And here is the key move: every framework and tool we are about to walk through ultimately compiles down to these same three languages, because they are the only thing a browser can run. The fancy names are conveniences for you, the person writing the code. The browser never sees them.

JavaScript, then TypeScript

JavaScript is the foundation - the one programming language every browser can execute, and the engine behind anything interactive on the web. If a page does something rather than just sitting there, JavaScript is doing it.

It has one well-known weakness, though: it is famously easy to make a small mistake - a misspelled property, a number where you meant text - and not find out until the code is already running in front of a user. That is the problem TypeScript exists to solve.

TypeScript is not a different language. It is JavaScript with a safety net bolted on: you label what kind of value each piece of data is supposed to be - text, a number, a list of customers - and a checker flags it the moment something does not line up, while you are still writing, long before anyone visits the site. Think of it as a pre-flight check for your code.

When it is time to ship, all of those labels are stripped away and what is left is plain JavaScript - exactly what the browser wanted all along. You get the safety during development and pay nothing for it in production. In practice you will spot this in the file names: a TypeScript file ends in .ts, or .tsx once it also contains React.

React: building with pieces

Now that we can write JavaScript safely, we need a sane way to build an actual interface. That is React.

React is a JavaScript library for building user interfaces out of components - small, reusable pieces you assemble like building blocks. A button, a navigation bar, a product card: each is a component you define once and reuse anywhere, and each can hold its own logic for what to show and when to change. Build a complex page out of simple, repeatable parts, and you never have to repeat yourself.

The other thing React gives you is JSX, a syntax that lets you write HTML-like markup directly inside your JavaScript, so a component's structure and its behavior live together in one place instead of being scattered across separate files. That is why a React file written in TypeScript carries that .tsx extension - it is TypeScript plus this HTML-in-JavaScript syntax.

React's job, in a sentence: decide what shows on screen and when it changes. What it deliberately does not handle is how any of it looks. That is the next layer.

Tailwind: styling without leaving your components

If React is the skeleton and the nervous system, Tailwind is the skin and the clothes.

Styling on the web is the job of CSS, and the traditional way to do it is to write your styles in separate files, away from the markup they apply to. Tailwind flips that around. It is a CSS toolkit built from small, single-purpose utility classes you apply right where you are building - so bg-blue-500 p-4 rounded-lg gives you a blue background, some padding, and rounded corners, without ever leaving the component or opening a separate stylesheet.

A few things made Tailwind the default choice for modern apps:

  • Speed. You style as you build, in one place, instead of bouncing between files.
  • Consistency. The utilities pull from one shared design system, so spacing and color stay even across the whole app by default.
  • It plays beautifully with AI. Coding assistants generate clean, working Tailwind remarkably well, which makes it a natural fit for an AI-assisted workflow.

One modern touch worth knowing: Tailwind now keeps its configuration - your custom colors, fonts, and spacing - right inside your CSS, rather than in a separate JavaScript config file. One less moving part, which turns out to be a recurring theme in this stack.

Next.js: the framework that ties it together

So far we have a safe language (TypeScript), a way to build interfaces (React), and a way to style them (Tailwind). What we do not have is everything around the edges that a real app needs: pages and URLs, a backend, performance tuning, a sensible project structure. That is what a framework provides, and for React, the standard one is Next.js.

Next.js is built on top of React and adds the scaffolding that turns a pile of components into a shippable application:

  • Routing by folders. Your file and folder names become your app's URLs. The file for your about page simply lives at the path that serves /about, with no separate routing configuration to maintain.
  • Rendering on the server. Next.js can build pages ahead of time or render them on the server and send finished HTML to the browser. That means faster first loads and pages that search engines and AI crawlers can actually read - a real edge for getting found. Some components can even run entirely on the server and never ship to the browser at all, which keeps the app lean.
  • A backend in the same project. This is the one that surprises people. Next.js lets you write backend code right alongside your frontend, in the same codebase and the same language.

That last point deserves a moment, because it is where "frontend framework" undersells what is going on. Inside a Next.js app you can create backend endpoints that do real server work: reaching out to other services - a database, a payment processor, an AI model, an automation platform - and also receiving data those services push back to you when something happens, like a payment clearing or a form being submitted. Both directions are just HTTP requests. When your code asks a service for something, that is an API call; when an outside service pushes data to you the instant an event happens, that is a webhook, essentially an API call in reverse. Same plumbing, opposite direction.

The upshot: the same language and the same project hold both the screen the user sees and the logic running behind it.

Node.js: JavaScript off the browser

There is one piece left, and it is the one that makes "JavaScript everywhere" literally true. A browser can run JavaScript, but your own computer and your production servers are not browsers. Node.js is what lets JavaScript run anywhere else.

Node is not a library or a framework - it is the runtime, the engine that executes JavaScript outside the browser. It is what is actually doing the work when you:

  • run the app on your own machine while building it (the command that starts your local dev server),
  • compile the finished app for release (the build command), and
  • run that backend code in production once the app is live.

It is also what npm, the tool that installs and manages all the other pieces - React, Next.js, Tailwind, and the rest - runs on top of. When people say the whole stack is "JavaScript from top to bottom," Node is the reason that is not just a slogan: the same language runs in the browser, on your laptop, and on the server.

From your machine to the world

Knowing the pieces is one thing; seeing how they get from your editor to a live website ties it together. The modern workflow is refreshingly short:

  1. Write it, with an assistant. You build locally in TypeScript and React, styled with Tailwind, inside the Next.js structure - increasingly with an AI coding assistant like Claude Code working alongside you. A local dev server shows your changes the instant you save.
  2. Push it to GitHub. Your code lives in a GitHub repository, which keeps a full history of every change, makes collaboration and rollbacks easy, and acts as the single source of truth.
  3. Let it build and deploy itself. This is the satisfying part. The moment you push to GitHub, your hosting platform notices, runs the build automatically - checking your types, bundling your React, compiling your Tailwind into a lean stylesheet, optimizing everything - and publishes the result to a global network of servers. Minutes later, your change is live.

For a Next.js app, the natural home for that last step is Vercel - the company that builds Next.js. Because the same team makes both, everything works out of the box, with no extra adapters or plugins to bolt on. Netlify and others can host Next.js too, often with a plugin or two to fill the gaps.

The closer you stay to native, the fewer moving parts there are to break. Every plugin or adapter you add is one more thing to keep working - so reaching for the option that already speaks your framework's language is usually the quietest path.

Why this became the standard

None of these tools won by accident. Stacked together, they reinforce each other:

  • One language, end to end. Frontend, backend, build tools, even your AI assistant's output - all JavaScript. Less context-switching, and logic can be shared between the browser and the server.
  • Type safety as a default. TypeScript catches a whole class of bugs before they reach a user, and doubles as documentation your editor can read.
  • Reusable components. Build your interface from tested, repeatable pieces instead of one sprawling page.
  • Deploy by pushing. Code goes live by committing to GitHub. Full history, instant rollbacks, and a preview link for every change before it hits production.
  • No servers to babysit. You never provision or patch a machine. Your code still runs on real servers - managed behind the scenes - but the hosting platform handles all of it, scaling up and down with traffic automatically.

That last point is worth saying plainly, because the word "serverless" trips people up:

"Serverless" does not mean there are no servers. It means you never have to think about them. The servers are still there, running your code - someone else just owns the headache of keeping them alive.

The plain version

Strip away every brand name and here is the whole thing:

You write in TypeScript (JavaScript that catches your mistakes) using React (which builds the interface from reusable pieces), style it with Tailwind (utility classes for how it all looks), organize it with Next.js (which adds pages, server rendering, and a backend), run it all on Node.js (JavaScript outside the browser), commit it to GitHub, and let Vercel or Netlify build and ship it.

But underneath the entire tower:

A modern web app is just JavaScript and CSS running in a browser. Every tool stacked on top of that exists for one reason - to let a small team build something fast, polished, and reliable that used to take a roomful of specialists.

That is the secret the vocabulary hides. The stack is not a wall to scale. It is a set of layers, each doing one job, that add up to something far greater than the sum of their parts.