Projects · What I'm known for

mattfor.com

Active 2026 – now Designer, developer and operator

This site: a LittleBigPlanet 2 flavoured portfolio, blog and hangout built from scratch on Bun, served from the Raspberry Pi on my desk along with everything else I host.

You're standing in it. mattfor.com is a pod floating in the cosmos, the way LittleBigPlanet 2 has one, made from the game's own cardboard, felt and stickers, with everyone who's on the site at the same time in it together. It's my portfolio, my blog and a little hangout, and it's built from scratch, from the server to the last sticker.

What's in it#

  • Live, together. Other visitors' cursors with name tags, a shared chat with LBP stickers, score bubbles to pop with a leaderboard for everyone on the site, a sticker album, an old-school visitor counter, and what I'm listening to right now.
  • Projects as levels. /projects is a WebGL2 moon you spin to pick a level, with live stats (Relaxy's users, npm and PyPI downloads, GitHub stars). Some projects have an LBP-style tutorial: a cardboard video board drops in on two strings, the curtains part on a little set, and the Queen talks you through it.
  • The jukebox. LittleBigPlanet's soundtracks play on every page, and the walls dress up for the world each track is from. It even builds itself in front of you, Create mode style.
  • The little things. Weather in spells, walls decorated just for you that change daily, a Konami code party, the Cakeling, a portal gun, a xylophone in the logo.
  • Create mode. The site edits itself: posts, projects, pages, the "Stuff I like" boards and every setting, with a version history, scheduled publishing and passkey sign-in.

How it's built#

  • Server: one Bun process. Bun.serve does the routing, a page cache, static files with hashed addresses, the admin API and a WebSocket for the live parts (presence, batched cursors, chat, bubbles). Pages are HTML templates that escape by default, and the content is Markdown with front matter in plain files, watched and reloaded when they change.
  • Client: vanilla TypeScript and CSS, no framework, bundled by Bun. Scripts load after the first paint, decorations lazily, and loops that are out of sight hold still. Sound is Web Audio, falling back to pooled <audio> elements in browsers that have it switched off.
  • Assets: the LBP textures, stickers and sounds come through a Python pipeline, the 3D bits (the pod, Sackboy) are rendered from the game's models with three.js in headless Chromium, and the 88x31 buttons are drawn from HTML. When my avatar changes, the Pi draws the link previews and my button again by itself.
  • Privacy: no trackers, no ads and no cookies for visitors. Visit counts come from a daily-salted hash, and the one thing kept in your browser without you doing anything asks first.

The Pi it runs on#

Everything is served from a Raspberry Pi 4 (8 GB) running Void Linux. Besides this site it runs all of Relaxy! (the bot, its dashboard, website, status page and CDN), a Matrix homeserver with its API, an IRC server, a Minecraft server, AdGuard Home with unbound for DNS, and the ETB speedrun bot.

  • One boot script that never gives up early. Every step is isolated and logged with real diagnostics, services are checked by probing them rather than by asking whether their container exists, and every wait is bounded, so one broken thing can't take the rest down with it.
  • Containers and services. Most things run in their own Podman container, the system services under runit, with Caddy in front as the reverse proxy and a web application firewall.
  • Watching itself. A prober checks every service every ten seconds and feeds the public uptime page, a hardware watchdog resets the board if it ever hangs, the firewall keeps SSH in its own priority band so the box stays reachable when it's struggling, and a daily file-integrity check posts only what's new.
  • A control page. Services can be switched off, on, or kept from starting at boot from a page, and the stats live behind a passkey door that fails closed.

Keeping all of that up on a single-board computer is most of what taught me to care about memory, isolation and failure modes.