Web craft

A field guide to modern web building

• 11 min read

The shape of a site in 2026

Building for the web has never had more good options or more expensive wrong turns. The stack you pick decides how fast the site loads, how long a change takes and how many people can safely work on it at once. This is the tour I give someone starting a new project, in the order the decisions actually arrive.

  • Render as early as you can.
    Anything that can be decided at build time should be. It costs nothing at runtime and it cannot break in production.
  • Ship the smallest amount of behaviour.
    Interactivity is the expensive part of a page, and most pages need very little of it.

“The fastest framework is the one you did not send to the browser.”


The wrong turns worth naming

Four decisions cause most of the pain I get called in to look at.

  1. A client framework for a document
    Marketing pages, docs and blogs are documents. Rendering them through a runtime that has to boot before the text appears is a self-inflicted cost.
  2. State everywhere
    A global store introduced in week two will still be there in year three, holding four values that belonged in the URL.
  3. Design tokens invented twice
    Once in the design tool, once in the code, and never the same. Pick one source and generate the other.
  4. Deferring measurement
    Performance is not a phase. A budget checked on every change is cheap; a rescue project is not.

💡 Pro tip: write down what has to be interactive before choosing anything. The list is usually four items long.


Pick the rendering strategy first

Everything else follows from this one choice.

  • Static, if the content changes on a human schedule.
    Build it, put it on a CDN, and stop thinking about servers.
  • Server-rendered, if the page depends on who is asking.
    Dashboards, accounts, anything behind a login.
  • Client-rendered islands, for the handful of widgets that need state.
    A carousel and a filter panel are not a reason to render the whole page in the browser.

🎯 How to do it: sketch the routes and label each one static, server or mixed. If more than a third are mixed, the boundaries are wrong.


Style with the platform, not around it

The CSS story got dramatically better and most projects have not noticed.

  • Container queries removed the last real argument for measuring elements in JavaScript.
  • Custom properties make theming a one-file job and survive being read by a human.
  • Cascade layers let a design system and a page override each other predictably instead of by specificity accident.

📊 A useful budget: under 60 KB of CSS and under 100 KB of JavaScript on a content page. Both are generous. Both are exceeded by default in most starters.


The build, end to end

1. Content in files

Markdown or a small typed collection, versioned next to the code. Review happens in the same place as everything else, and a rollback is a revert.

2. Components that render on the server

Keep them dumb, keep them typed, and pass data down rather than fetching inside them. Anything that needs the browser gets its own small island.

3. One deployment target

Static output to a CDN, previews per branch. If the deploy is boring, people deploy often, which is the entire point.

🎨 On assets:

  • Vectors for anything drawn; they scale and they diff.
  • One font family, one variable file, subset to the characters you use.
  • No third-party embed until someone can name what it earns.

What I would keep from the last decade

Typed interfaces, component thinking, and preview deployments. Those three changed how it feels to work on a site. Nearly everything else that arrived alongside them turned out to be a way of paying at runtime for a decision that could have been made at build time.

🌟 Final takeaway: choose rendering per route, style with the platform, keep content in files, and measure the two budgets on every change. That is the whole guide.


Afterword: the boring benchmark

The site this article lives on is static, ships 18 KB of JavaScript across all pages and renders its largest page in under 400 milliseconds on a cold cache over a throttled connection. None of that required a clever framework — only the decision not to send work to the browser.

Take your slowest page, list what on it truly needs the browser, and delete the rest. That first pass usually pays for the week.

Tomas VidalFebruary 6, 2026