All posts

17 April 2026

Why we ship static

This site is prerendered HTML on a CDN. Here is the reasoning, and why we think most small-studio websites should be the same.

  • engineering
  • infrastructure

The Vantara Labs company site is, by design, a pile of prerendered HTML files on a CDN. No server rendering, no edge functions for anything reader-facing, no database. One Cloud Function exists for contact-form submissions, and that is the full dynamic surface.

That sounds austere, and in 2026 it probably reads as a little old-fashioned. A lot of the tooling ecosystem has moved towards server-rendered, edge-first, "resumable" frameworks that do impressive things. We looked at that end of the dial and chose the quiet end on purpose. Here is the reasoning.

What "ship static" actually means for us

Concretely: every page on this site is generated at build time by nuxt generate, uploaded to Firebase Hosting, and served from the nearest edge PoP to the reader. When you hit vantaralabs.co.uk/about, you are getting a prebuilt about/index.html, not calling a function.

We keep one tiny dynamic bit, the /api/contact Cloud Function, but that is gated behind a form submission, not on every pageview. The blog, the product pages, the RSS feed, the sitemap, the Open Graph images: all built once, served many times.

Why, in order of importance

1. The site is read far more often than it is written

We will update this site a few times a week at most. It is read thousands of times between updates. Rebuilding on every request (even with caching in front) is paying for something the reader never benefits from.

Build-time rendering inverts the cost: we pay once, during the push, and every subsequent reader gets a file off a CDN. The only time a reader waits for compute is when the author did something new.

2. The failure modes are smaller

When a static site breaks, it breaks during CI. Our worst-case deployment failure is "the build fails and the previous version stays live", which is a normal day. We cannot push a regression that only shows up for one in a thousand visitors because our infrastructure doesn't have thousand-visitor variance. Every reader gets the same HTML.

No database means no database outage. No server runtime means no runtime upgrade breaking a library at 03:00. No regional failover complexity because CDN PoPs do that for us.

3. It costs approximately nothing

Firebase Hosting's free tier serves 10GB of egress per month before any cost kicks in. Our site is a few hundred KB of HTML, images, and fonts per pageview. Back-of-envelope: we would need to serve roughly 50,000 pageviews a month before we pay a penny.

The Cloud Function for the contact form is the only thing metered on invocations, and that is a handful of form submissions a day at most.

A small studio's website budget should be "the domain renewal and nothing else" until we are at a size where that assumption breaks.

4. Determinism makes compliance boring

UK GDPR, the Companies Act 2006 disclosure requirement, ICO guidance on cookies: all easier to comply with on a static site, because:

  • There is no server-side personal data processing. We know this because there is no server-side anything on page loads.
  • Consent Mode v2 can default to "denied" without the analytics ever having loaded, because no third-party script runs until the reader opts in. Which is the whole point of Consent Mode v2.
  • Auditing is literally reading the files we ship. The HTML shipped to readers is identical to the HTML in the repo's .output/public folder. No hidden runtime branch.

What we give up

We are not pretending the trade-off is free. The things we cannot do on a static site:

  • Personalisation on pageload. The same HTML goes to everyone. If we needed per-reader content (e.g. a logged-in dashboard), the products would need server rendering. They do, and they live on their own domains with their own frameworks.
  • True real-time content. If something breaks into the news and we want a blog post up in 90 seconds, we wait on a build. For a company site, this is a feature, not a bug.
  • Runtime A/B testing. We do not need it yet. When we do, we will reach for static edge rewrites before anything heavier.

Where static stops being the answer

For the portfolio's actual products, Pelosi Tracker and Leyden, static-only would be wrong. Those products serve live-updating data, process payments, gate features behind auth. They need server runtime and we give them one.

But the company website is a brochure and a blog. We would have to invent requirements to justify running a server for it.

The boring recommendation

Most small-studio and freelance websites are over-engineered. Nuxt, Next, Astro, SvelteKit all have "generate static" as a first-class target. Pick your favourite framework, generate the site, host it on Cloudflare Pages, Netlify, Firebase Hosting, or GitHub Pages, and go build the product.

The exciting frameworks will still be there when you actually need them.


Part of a short series on how the Vantara Labs site is put together. Next one: how we manage the GCP side of things with Terraform. Subscribe via the RSS feed if that is your thing.