← Journal

Eine Website mit einer Abhängigkeit

2 min readweb, tooling

Diese Website hat kein Framework, keinen Bundler und keine CSS-Library. Hier ist der ganze Build, und was wir gewonnen haben, weil wir ihn selbst geschrieben haben.

The site you are reading has exactly one development dependency: the TypeScript compiler. No framework, no bundler, no CSS toolkit, no animation library. This is not a purity contest. It is a bet that for a site like this, the tools would cost more than the code they save.

The whole build fits on a screen

The build is a TypeScript file that Node runs directly, thanks to its built-in type stripping. It does five things:

  1. Copies static files (fonts, favicon).
  2. Flattens @import chains into a single stylesheet, so the browser makes one request.
  3. Resolves HTML includes like <!-- @include partials/footer.html -->, with simple variables.
  4. Generates one page per project and per journal note from a template.
  5. Runs tsc, which emits native ES modules the browser loads as they are.

The include resolver is twelve lines. It has a test. When something breaks, we read twelve lines.

Native modules are good now

We do not bundle. Each TypeScript file becomes one small module, and the browser fetches them over HTTP/2 in parallel. The files are tiny, they cache independently, and changing one line invalidates one file, not a 300 KB bundle.

Top level await lets the translation dictionary load before any module that needs it, with no loader code at all:

let dict = {}
if (lang !== 'en') dict = await (await fetch(`/i18n/${lang}.json`)).json()
export const t = (s) => dict[s] ?? s

Utility classes, written by hand

We like utility classes: they keep markup honest and styles predictable. So we wrote our own, in small files grouped by concern: layout, spacing, typography, colour, effects, responsive variants. Around a few hundred lines in total, and every one of them is used.

Animations without a library

Every moving thing here runs on one shared requestAnimationFrame loop that stops itself when nobody is listening. Springs are three lines of physics. Liquid shapes are a fragment shader. Canvases pause when they scroll out of view. Reduced motion settings are respected everywhere, because some people get sick from all this, and that matters more than our fun.

What it cost, what it bought

It cost a few days of writing things a library would have given us. It bought a site we understand completely, that builds in about a second, and that will still build in five years without a dependency audit.

The best code is the code you never had to install.

That is not a rule for every project. Sometimes a framework is exactly right, and we use it. But it is worth asking the question every time, instead of starting from the answer.

Von Menschen geschrieben. Mehr Notizen →