A folder of files, one small Python server, and no build tool to keep updated.
This site is plain HTML and CSS with a little JavaScript for the theme toggle. No framework, no bundler, no dependency tree. The server in front of it is a few hundred lines of Python, standard library only.
Why no framework
A site this size does not need one, and every layer I don't add is a layer I don't have to patch, upgrade or debug. The parts I did want from a framework — caching, compression, headers, clean 404s — turn out to be a few dozen lines each.
What the server does
- serves
public/and nothing else;..and dotfile access return 404 - gzip for text over 512 bytes
ETag(hash of the body, cached by mtime) andLast-Modified, with 304 replies- security headers on every response: CSP,
X-Content-Type-Options,Referrer-Policy, HSTS,frame-ancestors 'none' - maps the bare domain to
wwwwith a 301 — including onHEAD, because a redirect that carries a body on aHEADrequest makes proxies complain - a real 404 page with status 404, not a friendly page served at 200
/healthzfor a one-line check
The caching trap
HTML is served private, no-store, because the response varies by client IP and must never land in a shared cache. Static assets get a normal max-age.
The catch is the CDN edge in front: it caches CSS and JS for four hours and ignores the origin's five minutes. Change a stylesheet and the browser receives new HTML with old CSS — the layout looks broken and nothing in the logs says why. The fix is a version query on every asset link (styles.css?v=14), bumped whenever the file changes. It isn't elegant. It is honest about how the edge behaves.
Owning the boring parts
Caching, headers and redirects are small, well-understood problems. Having written them myself, I can follow the whole path from request to response without opening anyone else's source.