Refactoring My Static Site in 2023

Published on

When I last redesigned, I was tired of my content management system. I already authored posts with Markdown and HTML, my contact form seemed hellbent on delivering junk while losing legit messages, and social media had long ago absconded with my commentors. I did some cursory maintenance every few months to coax my CMS into serving the same posts it always had, and watched the experience slowly degrade with each deprecated function call or abandoned plugin. It was time to make the site static.

Unfortunately, I didn’t love the static site generators of the day. Eleventy and Astro didn’t exist yet. I found Jekyll a bit inflexible, Hugo too overwhelming to configure, and Metalsmith too slow.

So I cobbled together a Frankenstein’s monster of Node scripts, Gulp tasks, preprocessors and transpilers. It rendered my Markdown content, it automatically polyfilled my “futuristic” CSS and JavaScript, and it knew when to compile a single post or the whole dang site. I loved it!

For a couple of years, anyway. Over time, three big issues revealed themselves…

Too Many Dependencies

My build process depended on just under 60 packages, each with dependencies of their own. Those with frequent updates would inevitably become blocked by those that were stale or abandoned, which meant I’d have to replace some to upgrade others. Compound that over a few years, and I was stuck spinning up an unsupported old version of Node to run a tech stack frozen in time.

Too Reliant on Speculative Standards

I made heavy use of PostCSS Preset Env and Babel to make my “modern” code backwards-compatible. In theory, those automated polyfills should have fallen away as browser support improved. In practice, that only works when the CSS you write resembles the standards that actually ship and your dependency upgrades aren’t stuck in a log jam.

Too Little Fun

At first, rolling up my sleeves and tinkering with my tailor-made environment was kind of exciting. But the more effort it demanded to keep it going, the more I resented the time it took away from writing, designing or coding something human beings would ever experience.

Clearly, a refactor was long overdue. I needed to reduce dependencies, simplify configuration, and get back to what I found fun about maintaining a personal website.

My New Setup

For the content itself, this site is now built with Eleventy. I’ve used Eleventy on several other projects, and I’m always impressed by its speed, flexibility and stability. It re-builds all 350+ pages of this site in less than two seconds. And I’ve had lovely interactions with Eleventy’s creator and community.

I’ve augmented stock Eleventy with plugins for feed generation and syntax highlighting, html-minifier-terser to optimize HTML before it’s deployed, and some custom filters using markdown-it and Luxon (both of which Eleventy already uses under the hood).

PostCSS and its import plugin bundle my styles, with CSSNano for optimization. The only future specification I’m polyfilling is Custom Media.

I still use GSAP for complex animations, but I’ve replaced my Snap.svg dependency with Polymorph. I tried esbuild to see what all the hype was about, but found Rollup easier to configure. I used the first-party CommonJS, Node Resolve and Terser plugins.

I wasn’t happy with any of the cache-busting replacements I found for gulp-rev, so I mimicked its behavior in a custom Node script using fast-glob (another existing Eleventy dependency), rev-file (which gulp-rev uses) and replace-in-file.

I use del-cli for build directory cleanup, concurrently for running tasks in parallel, boring ol’ rsync for deploys and Dependabot to lessen future dependency slippage (🤞).


Overall, the new setup reduces the number of dependencies from 59 to 22, and the amount of configuration code from 1,245 lines to 223. That’s 62% fewer dependencies to update and 82% less configuration to wade through!

Resolving that technical debt had user-facing benefits, too. The size of my global CSS fell a modest 5%, but JavaScript is down 57% (and that’s before any compression).

Most importantly for a personal site: I’m having fun again! I’ve already made a handful of small improvements (respecting reduced motion preferences, underlining links, balanced text wrapping, blocking ChatGPT), but there’s more I’d love to do. I’d like my “Projects” section to highlight some of the amazing work my team at Cloud Four’s been doing and memorialize the games you can’t play anymore. I’d like my journal to include my sketchbook, my speaking gigs, maybe even my old web­comics. I’d like to try some wide-gamut colors or a new typeface.

Time will tell which improvements I’ll prioritize. History shows I’ll probably end up shaking my fist at certain decisions in a few years time. But at least for now, I can let this website be a worry stone again.