Open the source of this page and you'll find HTML. Not a mounting point for a client-side router, not a hydration payload — the actual words, in the actual document. The stylesheet is a stylesheet. The JavaScript is a few hundred lines of it, in three files, written by hand.
This is not how most marketing sites get built, and we want to be clear that it isn't a rule we apply everywhere. It was the right answer here, for reasons that are worth spelling out — because the same reasoning is what we bring to a client's architecture decisions, where the stakes are considerably higher than a five-page site.
What a build step actually costs
The cost of a toolchain isn't the afternoon you spend setting it up. It's the decade afterwards.
A site built on a framework acquires a dependency tree. That tree needs updating, because some of it will turn out to have security advisories. Updating it occasionally breaks the build, usually at the least convenient moment. The build itself depends on a runtime version, which gets deprecated. The hosting platform that made deployment a one-click affair changes its pricing, or its API, or is acquired.
None of these are hypothetical. They're the ordinary weather of software maintenance, and every one of them is a small tax on a site whose content changes a handful of times a year. Three years on, the most common failure mode for a brochure site isn't that it broke — it's that nobody can build it any more, so nobody touches it.
The question isn't "what's the best way to build this?" It's "what will this cost to still own in five years?"
What we gave up
Being honest about the trade is the whole point, so: we gave up real things.
- Componentisation. The page header exists in five HTML files. Change it and you change it five times. A template engine would fix that, and if this site grows past a dozen pages we'll add one.
- Type safety and linting on the JavaScript. At a few hundred lines, code review covers it. At a few thousand, it wouldn't.
- Asset hashing. No bundler means no content-hashed filenames, which took some care to get right — more on that below.
- The ecosystem. Every problem we hit, we solved ourselves rather than installing something.
Those are real losses. They're just smaller, for this site, than the maintenance burden they'd have offset.
What it bought
The site makes no third-party requests. No fonts from a CDN, no analytics loaded before you've agreed to it, no tag manager. That isn't a performance flourish — it's what makes a strict Content-Security-Policy possible, and a strict CSP is a genuine security control rather than a header you copied from a blog post.
It also means there's nothing to go stale. The deployment is a container with a web server and some files in it. If nobody touches this site for four years, it will still build, still deploy and still serve, because there's no dependency in the chain that can rot.
The part we got wrong
Dropping the bundler meant dropping content-hashed filenames, and we initially served CSS and JavaScript with a one-hour cache lifetime. That seemed reasonable. It isn't: it means that for an hour after any deploy, returning visitors run a mix of old and new assets, with no way to tell which.
We found it the embarrassing way — testing a change that appeared to have
no effect, because the browser was faithfully running the previous
version. Assets are now served with no-cache, which still
caches them but forces a revalidation that an ETag answers in a few bytes.
That's the honest shape of this trade-off. Choosing fewer tools doesn't mean fewer problems; it means the problems are yours to understand. We'd rather debug a caching header we chose than a build pipeline we inherited.
When we'd choose differently
Most of what we build for clients is not a static site, and most of it does have a build step — because an application with authentication, state and a hundred screens needs the structure a framework provides. The consolidation work we describe on the work page runs on Angular, in a monorepo, with a full toolchain. That was the right answer for that problem.
The judgement isn't "simple good, complex bad". It's matching the machinery to the lifespan and the change rate of the thing you're building. A system edited daily by eight people justifies infrastructure that a site edited quarterly by one person does not.
Most of the expensive architecture we're called in to rescue wasn't badly built. It was built well, for a scale that never arrived.