# How do web apps work?

By Christian Genco. Published 2026-09-05.

> A web app is text, code, and a database talking to each other. This is a hands-on walkthrough: edit real HTML, real Ruby, and a real database table right on this page, and watch how a request actually gets built.

Every business runs on web apps. Checking a bank balance, ordering lunch, logging into your CRM: it's the same idea underneath, over and over.

Most executives have never seen what's actually happening when they click a button. That's fine. You don't need to write code to run a company. But the ideas underneath a web app are not complicated, and once you've seen them, a lot of confusing conversations with your dev team get a lot easier to follow.

I'm going to show you the whole loop with things you can edit yourself, right on this page. It takes a few minutes. We'll build up from a plain page to a program that reads and writes a real database.

## This is a web page

A browser asked a server for a file. The server sent back some text. The browser drew this. That's the whole loop, before we add anything to it.

_Interactive demo: a mini browser bar showing example.com/index.html, rendering a simple blog post card with a title, a one-line summary, and a Read more button. This is the same page the next demo will edit._

Nothing fancy happened there. A file went from a server to a browser, and the browser turned it into something you could read. Now let's look at what that file actually contained.

## The text the browser got

**HTML** is plain text with tags around it. A tag says what a piece of text _is_: a heading, a paragraph, a link. Try changing the tag, the words, or the inline style on the left, and watch the right side update as you type.

_Interactive demo: two panes side by side. Left is an editable index.html source textarea. Right is a mini browser rendering that HTML live. Typing in the HTML immediately re-renders the page on the right, and also updates the page shown in the previous demo above, since they share the same page source._

That's the same page from the last section, edited live. Scroll back up after you change it and you'll see it changed there too. A web page is just text, and tags are just instructions for how to draw that text.

Typing HTML by hand works for a page that never changes. Most pages need to change, so instead of typing the HTML, we write a program that builds it.

## Now a program writes the HTML

Here, a small program written in **Ruby** builds the HTML instead of a person typing it. Anything wrapped in `#{…}` gets filled in the moment the page is built, in this case, the current time. Press Run and watch the timestamp move.

_Interactive demo: three panes and a Run button. Left is an editable Ruby snippet that builds an HTML string, with a timestamp filled in via string interpolation. Middle shows the exact HTML text that Ruby produced. Right is a mini browser rendering that HTML. Pressing Run re-executes the Ruby and updates the timestamp, showing that a program rebuilds the page fresh on each run rather than serving a static file._

The timestamp only moves when you press Run. That's the real difference between a static file and a program: a static file always says the same thing, but a program rebuilds the page fresh every time someone asks for it. That's what "the server" is doing every time you load a page: running a small program like this one, right now, just for you.

But that program only knew one blog post, hardcoded right into the Ruby. A real site has thousands of posts. It needs somewhere to keep them.

## A database is a very strict spreadsheet

Same idea as an Excel tab: rows and columns. The difference is the rules. Every row has exactly the same columns, in the same order, with the same type of value in each one. No stray notes in a random cell, no merged headers, no second table hiding underneath the first. Click into a cell below and change it.

_Interactive demo: an editable spreadsheet-style table titled posts, with columns id, title, and body, seeded with three example blog posts. Every cell is a text input, and edits are shared globally on the page and read by the next demo._

This is the `posts` table. Every cell you just edited is live for the rest of this page, the same way a real database keeps whatever the last write left behind. Every user account, every order, every blog post on every site you've ever used is just rows like these, in a table like this one.

Now let's connect the two ideas: a program that writes HTML, and a table that holds the facts.

## Putting it together

The address bar says which row you want. Ruby reads that number, pulls the matching row out of the table, and drops its values into the HTML. One template, one row per page, thousands of pages. Change the number at the end of the URL below to 1, 2, or 3, then press Run.

_Interactive demo: three panes and a Run button. Left is an editable Ruby snippet that reads an id from the page's URL, looks up the matching row in the posts table with Post.find, and builds an HTML string from that row's title and body. Middle shows the produced HTML. Right is a mini browser with an editable address bar; changing the number at the end of the URL and pressing Run loads a different post from the same table using the same code._

Same code, different row, different page. If you edited the table a few sections back, your edit shows up here too, because it's reading the same table. That's a web app: a program, a database, and a template, wired together so one piece of code can serve every row.

So far, data has moved one direction only: database, then code, then HTML, then browser. A form sends it the other way.

## Sending data back

You type into a form and press Save. The browser sends what you typed back to the server, and the server writes it into a row. Nothing changes in the table until you press Save. Try it below.

_Interactive demo: two panes. Left is a mini browser showing an edit form for one post, with title and body fields and a Save button; typing does not change anything until Save is pressed. Right is the posts table from the earlier demo. Pressing Save writes the form's values back into the matching row of the table, showing that a form sends data the opposite direction: browser back to the database._

That's the missing half of the loop. A browser doesn't just receive pages, it can send data back, and a program on the other end decides what to do with it: usually, write it into a row.

## The whole loop

Put the last few sections together and you have the shape of nearly every web app in existence. A browser asks for a page. Code builds an HTML page, usually by reading a row out of a database. The browser draws that page. If there's a form on it, the browser can send data back the other way, and the code writes it into the database.

Everything else in a real app (logins, search, payments, permissions) is this same loop, repeated, with more rules attached at each step. Once you can trace a single click through those four moves, most conversations with your engineering team get a lot easier to follow.
