Old-School Front-End / 2026 ・ No.01

Old-School Front-End

Part 1: how a web page reaches the screen, and the plan for an expense app

Published

A mock-up of the finished expense app. A navy menu bar reads Expenses, My claims, Approvals and Dashboard, with Taro Arai (claimant) at top right. The claims list shows cards for 4 claims this month, 32,400 yen awaiting approval and 1 sent back, filter buttons by status, and a table of dates, purposes, amounts and statuses (Submitted, Approved, Sent back, Paid, Draft)
What we are building: the claims list of the finished expense app. It is a mock-up put together with Bootstrap 5.3.8, and over fifteen parts we will build the real thing. (The author's demo pages, captured with Chromium in a cloud sandbox on 17 October 2026. The browser frame was drawn in afterwards to make things clearer.)

This post starts a series on building the screens of a web system: the front end. Our project is something every company has, an expense-claim app.
These days you can ask an AI for "a screen like this" and get one without reading a line of code. This is the age of vibe coding.
This series goes the other way. We write HTML, CSS and JavaScript by hand, checking what every line means, with nothing fancier than Bootstrap and jQuery.
Hence "old-school". Over fifteen parts we will get the screen above working. Part 1 is the warm-up before we touch any code.

1

Old-school: the opposite of vibe coding

First, meet the two people who will keep us company. Their names are a little joke in Japanese: Furui contains the character for "old", Arai the one for "new".

The cast

$ </> ? Furui, the veteran Survived the jQuery golden age Keeps the in-house apps alive Taro Arai, the new hire A vibe coder: thinks AI can make any screen in seconds

FuruiArai, the screens for the new expense app are yours.

AraiLeave it to me! I'll ask an AI for "an expense-claim screen" and it'll be done in a second. Vibe coding!

FuruiI see. And can you read the code it gives you? If the total is off by one yen, where do you fix it?

Arai…I'd go with the vibe?

FuruiThat's the "vibe" part. This time you write it by hand, line by line. The old-school way.

AraiBy hand? Isn't that how they built things in the Stone Age?

FuruiStone Age is a bit harsh. The 2000s, at most.

Vibe coding is a term Andrej Karpathy, one of OpenAI's founding members, coined in February 2025: you ask an AI in plain language, accept the code it writes without reading it closely, and carry on by feel. It caught on fast enough for Collins Dictionary to make it its 2025 Word of the Year. This blog covered it in the Dev Guide post Vibe Coding Field Notes. "Old-school" in this series means the exact opposite.

Vibe codingOld-school (this series)
Who writes the codeThe AI (you just ask)You
The code isNot read closelyChecked line by line
First screenVery fastTakes a while
When it breaksAsk the AI again (and hope)You can find what is wrong yourself
Good forPrototypes, throwaway toolsLong-lived business apps, reviewing AI-written code

Asking an AI is faster, no question. We write by hand anyway, for three reasons.

  • A person is still responsible for AI-written code — an expense app handles money. A total that is one yen off, or a missing input check, has to be found by someone reading the code. Code you cannot read is code you cannot check or fix
  • The foundations do not change — whether an AI wrote it or it was built with React or Vue, what reaches the browser is HTML, CSS and JavaScript. Know those, and you can see inside whatever you are handed
  • The old-school tools are still at work — W3Techs counted jQuery on about 64.5% of the websites it surveys in October 2026, and Bootstrap at about 75% of CSS-framework use. Company in-house systems have even more of them
CORE

This is not an anti-AI series. Once you can build something by hand, you ask an AI for the right things and can judge whether its code is any good. Writing by hand is the foundation for using AI well. The goal: to be able to build a business app's screens from start to finish without leaning on AI.

2

What we are building

An expense claim is how staff get back money they paid on the company's behalf (train fares, hotels on business trips and so on): they claim it, a manager approves it, and accounts pays it back. Here are the people involved and how a claim moves along.

Who moves a claim to which status

Draft Not sent Submitted To approve Approved To pay Paid Done Claimant (Arai) submit Approver approve Accounts pay Sent back Fix it send back (approver) fix, resubmit Example rules • Receipt required from ¥30,000 • No future dates • Dollars converted to yen

Each claim has a status, and every action by a person moves it to the next one. Showing that flow well on screen is where business apps earn their keep

Roughly, these are the features we will build.

UserWhat they can do
ClaimantWrite a claim (adding line items and attaching receipts), save a draft, submit it, see their claims and statuses, fix and resubmit a claim that was sent back
ApproverReview their team's claims, then approve them or send them back with a reason
AccountsMark approved claims as paid, see monthly totals as charts, print claims

There are rules to enforce, too. As on the expense page tested in the Dev Guide post Playwright in Practice: a receipt is required when the total reaches 30,000 yen, future dates are not allowed, dollar amounts are converted to yen, and so on. Part 9 covers how the screen enforces them.

NOTE

This series builds only the screen side (the front end). In place of a server that stores data, from part 10 we use a small stand-in server that pretends to be the real thing (a mock API). For production use, sign-in and input checks must also happen on the server, because checks on the screen side are easy to bypass in the user's own browser.

3

How a page reaches the screen

AraiYou type a URL and the page just appears. It's basically magic.

FuruiIt looks like magic because the steps behind it finish in a blink. Let's slow it down.

What happens inside the browser

Browser On your machine Server Where pages live 1 Order by URL (request) 2 HTML, CSS and JS arrive (response) HTML CSS JavaScript DOM CSSOM 3 Render tree Visible parts Layout Size, position Paint Fill pixels Screen Finally! 4 5 JavaScript rewrites the DOM Each rewrite reruns (4) and (5), so heavy scripts slow a page
  1. Order (request) — the browser asks the server at the URL for the page
  2. Delivery (response) — the server sends HTML. The browser then fetches the CSS and JavaScript files the HTML mentions
  3. Reading — the HTML becomes a tree of page parts (the DOM), the CSS becomes a list of style rules (the CSSOM), and together they make a tree of only what will be shown (the render tree)
  4. Arranging (layout) — positions and sizes are worked out for the width of the screen
  5. Painting — text and colour are drawn into the screen's pixels

The key player is the DOM. When JavaScript changes a page it does not edit the HTML file; it rewrites the DOM inside the browser. Each rewrite reruns steps 4 and 5, so careless rewriting makes a page sluggish. We will meet this again in part 8.

4

HTML, CSS and JavaScript

The three front-end languages are easiest to picture as a body.

Who does what

HTML Skeleton What is there <h1> <table> <button> CSS Clothing How it looks color: #c0392b; margin: 16px; JavaScript Muscle How it moves addEventListener textContent = Leave any one out and you do not have a business app

Seeing is believing. Here is the same claim form with the three added one at a time.

The same claim form in three stages. 1 HTML only: plain default styling, and the total stays at 0. 2 With CSS: a navy header, rounded inputs and a red button, but the total is still 0. 3 With JavaScript: the total shows 3,830, and pressing Submit displays 'Submitted! (Well, not actually sent anywhere yet.)'
One page, three steps: (1) HTML only, (2) add CSS, (3) add JavaScript. The look changes at step 2, but the total is calculated and the button answers back only at step 3. (The author's demo pages, captured with Chromium in a cloud sandbox on 17 October 2026. The browser frame was drawn in afterwards to make things clearer.)

With HTML alone (1), the inputs and button already work: you can type and you can click. It just looks plain, and the total stays at 0. Adding CSS (2) makes it look like a business app, but it still does no maths. Calculating, and reacting when you click, is JavaScript's job. Here is what each step added (excerpts).

<!-- (1) HTML: what is there -->
<p>Total: <output id="total">0</output> JPY</p>
<button type="button" id="send">Submit</button>

/* (2) CSS: how it looks */
button { background: #c0392b; color: #fff; border-radius: 8px; }

// (3) JavaScript: how it moves
document.querySelector('#send').addEventListener('click', () => {
  document.querySelector('#toast').hidden = false;
});

No need to understand it yet. HTML comes in parts 2 and 3, CSS in parts 4 to 6, and JavaScript in parts 7 to 10, one step at a time.

POINT

The basic habit is to keep the three in separate files (.html for HTML, .css for CSS, .js for JavaScript). Split by role, a change that is only about looks, or only about behaviour, touches just one place.

5

A little history

A series that calls itself old-school owes you a few old stories.

A front-end timeline (highlights)

1990 2000 2010 2020 1991 The web opens First site: info.cern.ch 1995 JavaScript Built in 10 days 1994 CSS proposed Looks split from HTML 1996 CSS1 A W3C Recommendation 2006 jQuery Smoothing browser quirks 2011 Bootstrap Released by Twitter 2021 Bootstrap 5 No more jQuery needed 2026 jQuery 4.0 And a Bootstrap 6 alpha * Our focus: the old-school tools, and the basics that last
  • 1991 — Tim Berners-Lee at CERN opens the web to the public over the internet. The first web server was info.cern.ch
  • 1994–96 — Håkon Wium Lie proposes CSS (October 1994). CSS1 becomes a W3C Recommendation in December 1996, fixing the idea that looks are written separately from HTML
  • 1995 — Brendan Eich at Netscape builds the first JavaScript prototype in just ten days in May; it is announced in December
  • 2006 — John Resig announces jQuery. It smoothed over the wildly different ways each browser had to be coded for, and spread fast
  • 2011 — Mark Otto and Jacob Thornton at Twitter release Bootstrap
  • 2021 — Bootstrap 5 no longer needs jQuery
  • 2026 — jQuery 4.0 arrives in January, its first major version in nearly ten years (dropping Internet Explorer 10 and older). In October the first Bootstrap 6 alpha is published

AraiJavaScript was made in ten days? Then we can finish this series in ten days too…

FuruiThe prototype took ten days. They have been fixing it for thirty years since. We get fifteen parts. More haste, less speed.

We plan to use the stable versions at the time of writing: Bootstrap 5.3 and jQuery 4.0.

6

Drawing the screens

Just as you draw a floor plan before building a house, you draw a plan before building screens. First, the list of screens and how you move between them. The small print says which part mainly builds each one.

The expense app's screens

Sign in Part 11 Claims list Parts 2, 6 Claim form Parts 3, 8, 9 Dashboard Part 13 Detail, approve Part 12 Printable claim Part 13

Next, the most important one, the claim form, in a little more detail. A drawing like this, without colour or decoration, showing only what goes where, is called a wireframe.

A wireframe of the claim form

Expenses Expense claim Purpose Date Item Amount Receipt 10/14 Train fare 1,480 — 10/15 Meeting tea 2,350 attached + Add a row Total ¥3,830 Save draft Submit 1 2 3 4 5 6 7 1 Heading 2 Purpose 3 Line items (rows can grow) 4 Add-row button 5 Total (calculated) 6 Receipt upload 7 Save draft / submit

Pencil and paper will do. What matters is checking that nothing is missing, not making it pretty

A plan surfaces questions before you build. What if a claim has more than ten line items? Are receipts only images, or PDFs too? Will anyone claim from a phone? Asking these up front saves rework later.

7

Getting the tools

You need just three tools, all free.

ToolForNotes
BrowserShowing and checking your screensThis series uses Google Chrome; Edge is almost identical
EditorWriting codeVisual Studio Code (VS Code). Syntax colouring and autocomplete help a lot
Live PreviewRefreshing the page each time you saveA VS Code extension from Microsoft that runs a small web server on your machine

One more essential tool comes built into the browser: the developer tools (DevTools). Think of them as an X-ray of the page. We will use them in almost every part.

The highlights of DevTools

Expense claim Elements Console Network Sources <html lang="en"> <head>…</head> <body> <h1>Expense claim</h1> <form>…</form> </body> </html> Elements See HTML and CSS, edit them live Console Try out JavaScript, read the errors Network Watch the requests (the star of part 10) To open: F12 or Ctrl + Shift + I (Windows), Cmd + Option + I (Mac)

Files go into folders by role, like this (this time we only make index.html).

keihi/The project folder ├─ index.htmlEntry page (now; the claims list from part 2) ├─ form.htmlClaim form (from part 3) ├─ css/style.cssLooks (from part 4) ├─ js/app.jsBehaviour (from part 7) └─ data/Sample data (from part 10)
8

Your first page

With the tools ready, let's make the first page. Five steps.

  1. Create a folder called keihi ("expenses" in Japanese) and open it in VS Code with Open Folder
  2. Create index.html, type in the code below and save (in an empty file, type ! and press Tab for an instant template)
  3. Install the Live Preview extension and open the preview with the button at the top right of the editor (or from the right-click menu)
  4. Change some text and save, and check that the preview follows along
  5. Open it in the browser, press F12 (Cmd + Option + I on a Mac) to open DevTools, and find the h1 in the Elements tab
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Expense System</title>
</head>
<body>
  <h1>Expense System</h1>
  <p>Under construction.</p>
  <p>Building work starts in part 2.</p>
</body>
</html>
The first page open in a browser: a large heading, Expense System, and two lines, Under construction and Building work starts in part 2
The first page, built in chapter 8. No CSS, no JavaScript: just plain HTML. (The author's demo pages, captured with Chromium in a cloud sandbox on 17 October 2026. The browser frame was drawn in afterwards to make things clearer.)
What you wroteWhat it means
<!DOCTYPE html>"This is modern HTML." Always the first line
<html lang="en">The box around the whole page. lang gives the language, which screen readers and translation tools use
<head>Information about the page that is not shown on screen
<meta charset="UTF-8">The character encoding. Without it, non-English text can turn into gibberish
<title>The title on the browser tab
<body>What is shown on screen
<h1>, <p>A main heading and a paragraph

Now let's break it on purpose. Delete </h1>, the heading's closing tag, and save…

The page with the heading's closing tag missing. The two lines of ordinary text are now as large and bold as the heading
Delete a single </h1> and the paragraphs after it end up inside the heading, all large and bold. The browser shows no error; it quietly does its best. (The author's demo pages, captured with Chromium in a cloud sandbox on 17 October 2026. The browser frame was drawn in afterwards to make things clearer.)

AraiWhoa, it's all heading now! But there's no error.

FuruiBrowsers are forgiving. Even with a mistake, they quietly do their best. Lean on that kindness and you'll have a hard time tracking bugs down later.

Look in the Elements tab of DevTools and you will see both paragraphs sitting inside the h1. "When something looks wrong, check the shape of the tree in Elements first." That is the first debugging step, and we will use it again and again.

9

The fifteen-part map

Finally, the road ahead. We are taking the stopping train, one station at a time.

Old-School Front-End: the route map

1 Setup 2 HTML 3 Forms 4 CSS basics 5 Layout 6 Bootstrap 7 JS basics 8 DOM, events 9 Validation 10 Fetch 11 Sign-in 12 Approvals 13 Charts, print 14 jQuery 15 Finish You are here Setup HTML CSS JavaScript Real app Finish
PartTopicWhat we build in the expense app
1The big picture, and setupThe plan, and a first page (this post)
2HTML 1: document structureThe skeleton of the claims list (headings, a table, links)
3HTML 2: formsThe claim form (inputs, choices, file upload)
4CSS 1: selectors and boxesStyling the list with our own CSS
5CSS 2: layoutHeader, menu and content placement; phone support
6CSS 3: BootstrapRebuilding the whole screen with Bootstrap
7JavaScript 1: the languageA function that adds up the total
8JavaScript 2: the DOM and eventsAdding and removing line items, a live total
9JavaScript 3: validationRules such as a receipt from 30,000 yen
10JavaScript 4: async and fetchLoading the list and submitting claims (mock API)
11Sign-in and switching screensDifferent screens for claimants, approvers and accounts
12The approval flowManaging draft, submitted, approved or sent back, and paid
13Totals and printingA dashboard with charts, and a printable claim
14jQueryRewriting parts 8 to 10 in jQuery and comparing
15FinishingQuality, safety and publishing, and the door to frameworks

The first half (parts 2 to 10) takes the three languages one at a time; the second half (parts 11 to 15) combines them into the features a business app needs. jQuery waits until part 14 because once you have written things in plain JavaScript yourself, you can see exactly what jQuery saves you.

§ — On one page, and what is next

  1. This is a fifteen-part, old-school introduction to the front end. The opposite of vibe coding: we build an expense app by writing HTML, CSS and JavaScript (plus Bootstrap and jQuery) by hand. That skill is also the foundation for using AI well.
  2. A browser shows a page by ordering, receiving, reading (the DOM and CSSOM), laying out and painting. JavaScript changes the screen by rewriting the DOM.
  3. The roles: HTML is the skeleton (what is there), CSS the clothing (how it looks), JavaScript the nerves and muscles (how it moves). Keep them in separate files.
  4. Before building, sketch the users, the flow, the rules, the list of screens and a wireframe. It saves rework.
  5. The tools are a browser, VS Code and Live Preview, plus DevTools. When something looks wrong, check the tree in Elements first.

AraiHTML next time! The building site gets its first pillars!

FuruiRight. We start with the skeleton of the claims list. Homework: break today's index.html, then fix it. Yourself, before you ask an AI.

References

Usage figures are from W3Techs (jQuery as of 17 October 2026, CSS frameworks as of 16 October 2026) and are shares of the websites that W3Techs surveys. Versions and release dates are from the jQuery blog and npm's publish records (the latest stable Bootstrap is 5.3.8; 6.0.0-alpha.1 was published on 8 October 2026). The ten days come from the paper by Wirfs-Brock and Eich (HOPL IV, 2020). The screenshots show the author's demo pages, captured on 17 October 2026 with Chromium (Playwright) in a cloud sandbox; the cover is a mock-up built with Bootstrap 5.3.8. The characters are fictional.

Old-School Front-End, part 1 — How a web page reaches the screen, and the plan for an expense app / 2026.10

← Back to all posts