HTML3000

A Better Way to Write HTML for Modern Apps

When Tim Berners-Lee invented HTML his idea was to share documents – scientific papers to be precise. This document shape is still with us after all this time. That's why we have elements like <article>, <aside>, <header>, <footer>, <p> and so on.

This works great for articles and blogs, but the web has changed. Today the majority of what we build are applications, not documents, and the metaphors of documents don’t always fit application interfaces. Carousels, badges, counters, avatars, alerts – none of these map neatly to <article>, <header>, or <p>. Instead, we’ve been shoehorning them into non-semantic catch-alls: <div> and <span>.

Why <div>s Are Harmful

<div>s are the duct tape of web development. They:

The irony is that React developers already know this. They write <Panel>, <Button>, <Logo>, <Nav> every day in JSX. Those are semantic! But paradoxically, the same community often declares that semantic HTML is "dead."

It most definitely isn't. In fact, semantic HTML is more important than ever.

HTML in 2025: Underused and Undervalued

The truth is, HTML and CSS in 2025 are more powerful than many developers realize. Features like CSS nesting, attribute selectors, and custom elements give us expressive, declarative tools that work everywhere without JavaScript or build systems. Put together, these practices feel futuristic – like coding in the year 3000! – even though most of them have been around for years.

That’s why I call this approach HTML3000.

The Principles

At its core, HTML3000 is about leaning into semantics and writing HTML that describes what an element is, not just how it looks. The key principles are:

The goal isn’t to throw out modern tooling. HTML3000 plays nicely with ERB, Hotwire, Stimulus, HTMX, React, Vue, Phoenix LiveView, and more. It’s "just HTML" but written differently.

Examples

Fixing the Tailwind website example

See the Pen HTML3000: Fixing the Now Playing Tailwind example by Fabio Neves (@fzero) on CodePen.

A javascript-free badge component

See the Pen HTML3000: Badge example by Fabio Neves (@fzero) on CodePen.

What You Gain Without <div>s

Why This Matters

Using semantic, declarative markup makes code easier to read, reason about and maintain. Instead of wading through endless utility classes you see the actual structure of your UI. Consistency emerges naturally and you’re nudged toward building standardized, reusable components.

Is this a design system? Nope! But any serious application needs consistent UX, and HTML3000 encourages you to think in components from the start.

Adopting HTML3000 Incrementally

You don’t need to rewrite everything overnight. Even small steps like replacing anonymous <div>s with meaningful custom tags can dramatically improve readability. You can go further by experimenting with attribute selectors or phasing out class-heavy patterns where they don’t serve you.

Further Reading

Looking Ahead

HTML3000 isn’t a framework, library, or package you install. It’s a set of practices that rediscover the expressive power of HTML and CSS – tools that already run everywhere. It’s about writing code for the web that’s semantic, declarative, and future-proof.

If the early web was about documents and the last decade was about JavaScript-driven UIs, perhaps the next step is recognizing that the simplest building blocks – HTML and CSS – already take us surprisingly far.

HTML3000 isn’t just a practice. It’s a promise: no more meaningless markup. Because the future of the web shouldn’t be meaningless.

HTML3000 © 2025 by Fabio Neves 🇨🇦🏳️‍🌈✊