back to articles

The Making of Brandon.xyz

Brandon Leigh-Bennett — Aug 17, 2023

In a sense, building brandon.xyz took years. I started developing a personal site many times, but never was able to finish due to being overwhelmed by the plethora of frontend and backend tools.

Each attempt was with a different technology, but none provided the level of control and flexibility I was looking for. Each framework usually tried hiding advanced behaviours behind depectively simple flags and options.

After working at companies like Active Theory, I've always wanted to make website that was more than what HTML and CSS, as capable as they are, are able to do.

Ultimately, I made the choice to simplify as much as possible to ensure an initial release which I could improve upon. I made brandon.xyz statically-generated HTML using a collection of small scripts and a few core tools.

Backend

Since it's statically generated, I don't actually write server code, but nonetheless there is still a lot of work going on to produce a bundle of HTML, CSS, and JavaScript which ultimately is still hosted somewhere.

To generate this bundle, I'm using JavaScript/TypeScript and JSX/TSX components to create HTML pages, and Esbuild to bundle clientside code.

Using Node.js' builtin tools, I can watch some source files, and when they change, rebuild the entire site instantaneously.

I came up with a simple structure in which every page (which could also be considered a component) is a module that exports some JSX, CSS, and JavaScript based on a page identifier.

Using basic file I/O, I can generate the directories and HTML files from the JSX that corresponds to that page.

I also:

  1. Aggregate all the exported CSS and merge it into one file, with each selector scoped to the aforementioned page identifier.
  2. Aggregate JavaScript functions exported from the page into a Map indexed by the page identifier, which allows me to hydrate a page on the client side at the appropriate time, similar to how Astro functions.

I'm writing this post in an MDX (Markdown) file. This allows me to write formatted posts without actually needing to construct raw HTML. I can also import any variable or run any script alongside Markdown, which as a programmer, makes me feel right at home.

Of course, all this Markdown is generated and exported directly to HTML, so it's very light on the client.

Frontend

On the clientside, I'm using vanilla JavaScript to scan for every same-origin href, and changing the default behaviour to actually fetch the HTML in JavaScript, and then replace the main content (e.g. everything excluding the navigation, in the normal case). Using simple promises and callbacks, you can be very intentional about when and how animations and scroll changes are made.

If a user lands on any URL, that page will be loaded and streamed to the browser directly — no need to wait to compile JavaScript and then generate the the HTML from there. If you try reloading this page for example, the browser will load again from the source extremely quickly.

Design

I went through many prototypes in Figma, capturing various designs. After some time I revisted all my designs, and tried to recreate the ones that just "felt" the best.

The same goes for the logo. I was inspried the modularity of K'nex, and the aesthetic of Wipeout 64 — both influential for me when I was a kid.

Why Not WebGL?

As a primarily a WebGL developer, I admit that I find HTML really frustrating and limiting at times. I would rather build my own system and be able to render text and images, and have full control over how everything is built and rendered.

But it's hard to overlook all of the things the browser gives you for free. It would take me years to be able to develop something approaching feature-parity. The ultimate goal of this website is to provide fast and accessible information about myself to help communicate past work, abilities, and values to other like-minded people.

This means it should be fast, accessible, and feature-rich to support me explaining things and referring to things.

I do want to extend it and add WebGL and other cool stuff, because that that's what I love doing and I want to share work with others, but I worry too much about optimization. There's a lot more to do to optimize it for every kind of device.

It felt like this was the easist approach. Whatever code I generate doesn't have to be the most efficient, because it's compiling and bundling everything into a format the browser likes.

For someone who likes to understand everything that's going on under the hood, this system is minimally complex while being maximally robust and flexible. It doesn't compromise on performance or robustness. That makes it fun to program in.