So here we are again. The tenth iteration of ewancroft.uk, and this time I did something I've been threatening to do for months: I nuked it from orbit and started fresh. The commit message says it all, really—just "RESET" in capital letters, because sometimes that's the only honest description of what you've done.
For those keeping track (and honestly, who is?), this is my tenth website redesign since I started properly building my digital presence. That's not a typo. Ten. I've rebuilt this thing more times than I've successfully completed a New Year's resolution, and considerably more often than I've managed to keep a consistent sleep schedule.
The Catalyst
It started with a post on Bluesky on 12 October 2025:
thinking i might completely redesign my website. It would give me the excuse to move to @leaflet.pub and decouple my website from vercel 504s. I'll stay using my current tech stack but I'm having a catch-22 situation because of the link rot it would generate. 😵💫
Vercel was having one of its moments. The site kept returning 504s, and whilst that wasn't technically my fault, it was definitely my problem. The idea of moving to Leaflet for blog hosting had been rattling around my head for a while—decentralised publishing on AT Protocol without being tied to any single platform's infrastructure seemed appealing.
But there was that catch-22: redesigning would break all the existing URLs. After writing an entire blog post about link rot and how I'd finally solved it with AT Protocol rkeys, the irony of breaking my own links wasn't lost on me.
Then again, sometimes you need to accept that perfect is the enemy of done, and link preservation is the enemy of actually fixing things. Two hours after that post, I opened the codebase and hit RESET.
The Breaking Point
Version 9 was... fine. It worked. The blog pulled from WhiteWind via AT Protocol, the now page displayed properly, and I'd even got the bloody theme toggle working after what felt like seventeen attempts. But somewhere along the way, it had metastasised into something unrecognisable.
The codebase had grown into this sprawling thing—122 files changed in that reset commit, 17,513 deletions, and only 2,505 additions to replace them all. That's not iterative improvement; that's architectural collapse disguised as feature development.
Looking at the git log, you can see where it started going sideways. First it was "just adding a blog feature," then "improving the layout," then "refactoring the components," and before I knew it I had custom CSS animations, three different approaches to parsing markdown, and enough TypeScript interfaces to make a C++ developer feel inadequate.
The final straw? Opening src/lib/components and finding 61 component files staring back at me. Sixty-one. For a personal website. A website that, let's be honest, gets visited by maybe a dozen people regularly (hi Mum), most of whom are probably just me checking if something deployed correctly.
I'd built a NASA-grade rocket ship when all I needed was a bicycle; a silver bullet for a chihuahua, if you will.
What Actually Survived the Purge
When you delete 17,513 lines of code, you learn what actually matters. Turns out, not much. The essential bits that made it through the RESET:
The Core Framework: SvelteKit stays, obviously. I'm not that masochistic. Svelte 5 with its runes and reactive state management still feels like the right choice, even if I occasionally want to argue with it about when exactly things should be reactive.
Tailwind: The utility-first CSS stays too. After years of writing custom CSS and dealing with specificity wars, I've made peace with writing class="flex items-center justify-between" directly in my markup. It's verbose in a different way, but at least it's predictable.
AT Protocol Integration: The whole point of this site is to aggregate my content from the decentralised web. Blog posts from WhiteWind, status updates from my custom uk.ewancroft.now lexicon—that's the foundation everything else builds on.
TypeScript: Type safety isn't negotiable anymore. I've been burned too many times by "quick fixes" that broke three unrelated things because JavaScript decided null and undefined should be spiritually different but practically identical.
What Got Binned
Here's where it gets interesting (or cathartic, depending on your perspective). The casualties of version 10:
All Custom CSS: Gone. Every single custom animation, every carefully crafted transition, every pixel-perfect layout tweak. The src/lib/css directory had grown to three files totalling 1,029 lines of custom styling. That's 1,029 lines of maintenance debt for visual effects that maybe 2% of visitors noticed.
The Component Library: Remember those 61 components? Down to... well, I'll need to build back up, but starting from zero this time. No more <ArchiveCard>, <PostNavigation>, <ThemeToggle>—at least not yet. If I need them again, I'll build them when I actually need them, not because they might be useful someday.
Blog Infrastructure: The entire src/lib/services/blogService.ts with its 412 lines of caching, parsing, and data transformation? Deleted. The custom markdown parser with plugins for syntax highlighting, maths rendering, and emoji support? Gone. I'll rebuild what's necessary when it's necessary.
Performance Optimisations: All that careful lazy loading, dynamic imports, and bundle splitting? Wiped out. Premature optimisation is the root of all evil, and I'd optimised for traffic levels I don't have and might never have.
The Documentation: Even the README got stripped down. The old one was 151 lines explaining how to deploy, configure, customise... for a codebase that no longer exists.
The Feeds: The /{blog,now}/{rss,atom} feeds are now either deprecated with HTTP code 410 Gone or simply show links instead.
The Philosophy Shift
Here's what I've realised after nine previous attempts: complexity isn't a sign of sophistication; it's a warning sign. Every "enhancement" adds surface area for bugs, increases build time, and creates mental overhead when you come back to the code months later.
Version 10 starts with a different question: "What's the minimum viable implementation that actually works?" Not "What cool features could I add?" or "How can I make this more sophisticated?" but genuinely, "What do I need right now to have a functioning website?"
The answer's surprisingly simple: a homepage, a way to display blog posts, and maybe a now page. That's it. Everything else is feature creep waiting to happen.
The Git Archaeology
Looking through the commit history of version 9, you can trace the evolution (devolution?) clearly. It started clean enough—"Initial commit," "Setup basic structure," "Add blog support." Then came the mission creep:
"Add table of contents for blog posts"
"Implement theme toggle with localStorage persistence"
"Add scroll-to-top button with smooth animations"
"Improve mobile navigation with hamburger menu"
"Add maths rendering with KaTeX"
"Implement syntax highlighting with rehype-highlight"
"Add reading time calculations"
"Implement progressive image loading"
None of these are bad features. But collectively? They're a maintenance nightmare, and more importantly, they're not why anyone visits the site. People (theoretical people, mostly) visit to read the blog posts, maybe check what I'm up to now, possibly follow a link to somewhere else. They don't need progressive image loading on a site that loads in 2 seconds anyway.
The Technical Debt That Accumulated
Version 9 had grown its own ecosystem of dependencies. The package.json ballooned to 81 lines of development dependencies alone—ESLint, Prettier, Tailwind plugins, PostCSS processors, TypeScript utilities. Some were essential, but a lot were "nice to haves" that added complexity without meaningful benefit.
The build process had become baroque. Vite preprocessing, PostCSS transformations, Tailwind purging, TypeScript compilation, SvelteKit's own build steps. It worked, but troubleshooting failures meant understanding five different toolchains.
And the Docker setup! I'd containerised everything because that's what you're supposed to do, right? Except I never actually used the containers in development, and deployment was to Vercel anyway, which has its own build pipeline. The Dockerfile and compose.yaml were security blankets I never actually needed.
The Rebuild: Starting Simple, Staying Simple
After that initial RESET commit on 12 October, I spent the next week building version 10 back up—but differently this time. The commit history tells the story better than I could narrate it:
12–13 October: The Foundation
Initial SvelteKit setup with Vite
Basic routing structure
Essential TypeScript configuration
15 October: The Component Renaissance
The irony isn't lost on me—after deleting 61 components, I started rebuilding them. But this time with discipline:
Migrated and modularised core UI components into a logical hierarchy
Created
components/index.tsfor centralised exportsMoved ProfileCard and StatusCard into
layout/main/card/—proper organisation, not sprawl
Then came the refactoring spree. Multiple commits on the same day, each focussed on a single improvement:
"Dynamic data and reactive metadata" for the site/meta page
Added proper layout and page load functions
Unified siteMeta handling with a dedicated helper
Simplified the Footer component (no more dynamically calculated copyright years)
16–17 October: Polish and Refinement
A flurry of late-night commits fixing the inevitable issues:
SEO improvements
Meta tag generation
Component cleanup
Styling adjustments
19 October: The Final Push
The last day saw 25 commits between 12:23 and 21:12. That's the sign of someone who's in the zone (or possibly losing their mind). Small fixes, refinements, the kind of tweaking that happens when you're 95% done and obsessing over the last 5%.
What makes version 10 different isn't the features—it's the restraint. Every component exists for a reason. Every helper has a clear purpose. The architecture is shallow on purpose, the abstractions minimal by design.
The Git Panic Moment
Just when I thought version 10 was safely pushed and under control, I almost nuked the entire redesign by accident. I was messing around with the git CLI, trying to tidy branches, and for a few terrifying minutes my production site turned into the dreaded default:
“Welcome to SvelteKit! :D”
Every carefully rebuilt component, every post aggregation, every bit of polish—vanished. Thankfully, I had a backup branch. I ended up removing the old (tainted) main and renaming the backup branch to main, but those few minutes of existential panic? Absolutely brutal.
The ordeal was worth documenting because it reminded me, yet again, that all the careful rebuilding in the world can be undone by a single misstep with git push -f. And yes, I publicly vented about it on Bluesky, because what else do you do when you almost erase a week of work? This was my reaction.
The Blog Platform Question
About that Leaflet migration I mentioned in the original post? It's still on the cards, actually. I've been refining my WhiteWind-to-Leaflet converter before making the switch—because if I'm going to migrate my entire blog, I'd rather do it properly than bodge it together and regret it later.
But here's what changed: I realised the platform choice wasn't the pressing problem. The infrastructure was. So before migrating anywhere, I solved the underlying issue: I made the blog platform-agnostic.
The site now intelligently redirects based on where a post actually lives. WhiteWind posts go to WhiteWind, Leaflet posts would go to Leaflet, and theoretically, any future AT Protocol blogging platform would work just the same. The redirect logic is simple but effective—check the post's collection type, match it to the appropriate platform, redirect accordingly.
It's the kind of solution that feels obvious in retrospect but took actual implementation to crystallise. Your blog becomes a portal rather than a platform, aggregating content regardless of where it was created.
So when I eventually do migrate to Leaflet (and I probably will, once the converter's polished enough), my website won't care. The URLs stay stable, the content moves freely, and readers won't notice anything beyond possibly cleaner URLs or better formatting. That's the beauty of building on AT Protocol—the frontend is interchangeable, the content persists.
The Lessons (That I'll Probably Forget Again)
This is redesign number ten. Statistically speaking, there's probably going to be a version 11 at some point. Maybe I'll actually remember these lessons then:
Start Small, Add Deliberately: Don't build features because they might be useful. Build them when they're actually needed, and not a moment sooner.
Question Every Dependency: Each package you add is a commitment. Not just to the initial setup, but to updates, compatibility, security patches, and understanding how it works when (not if) something breaks.
Resist the Siren Call of Sophistication: Advanced features are seductive. They make you feel like a serious developer. But a simple site that works beats a sophisticated one that's half-broken and impossible to maintain.
Delete Ruthlessly: Code you don't write can't have bugs. Features you don't implement can't break. Sometimes the best refactor is rm -rf.
Your Website Doesn't Need to Impress Other Developers: This one's hard. Part of why I kept adding features to version 9 was showing off technical skills. But the site exists for readers, not as a portfolio piece for other programmers to critique.
git reflog Is Amazing: Unintentional accidents can be devastating.
The Broader Pattern
Looking back at all ten versions, there's a pattern: I start with a vision, implement it, get excited about new possibilities, add features, complexity grows, maintenance becomes exhausting, I abandon it, repeat. It's the web development equivalent of that scene in every disaster film where someone says "This time will be different" right before everything explodes.
But maybe—maybe—version 10 breaks that cycle. Not through willpower or determination, but through a fundamental shift in what I'm trying to achieve. Less "impressive website" and more "functional home for my content." Less "showcase of technical skills" and more "thing that works without requiring constant attention."
The Commit That Started It All
That RESET commit on 12 October wasn't planned. I'd opened the codebase to fix something minor—probably a typo in a blog post or a broken link. Saw the sprawling mess it had become, and thought "What if I just... didn't?"
Three hours later, 17,513 lines were gone, and I had a blank slate. Scary? Absolutely. Liberating? More than I expected. There's something deeply satisfying about watching git diff scroll past with mostly red deletion lines.
The commit message was just one word: "RESET". No explanation, no justification. Sometimes that's all you need to say.
Version 11 Is Coming (Probably)
Let's be realistic: if history is any guide, there'll be a version 11. Maybe in six months, maybe in a year. I'll get excited about some new framework, or have a vision for a completely different approach, or just get bored with how version 10 looks.
But hopefully—hopefully—the lesson sticks: simpler is better, less is more, and your personal website doesn't need to be an engineering marvel. It just needs to work, display your content, and not make you want to scream when you open the code six months later.
What Comes Next
The honest answer? I don't know yet, and I'm trying to be okay with that. The old approach was to plan everything out, build the complete vision, then spend months maintaining something I'd already lost interest in. This time, I'm trying emergence over architecture.
Version 10 is live. It works. The blog integration is there (you're reading this, after all). The /site/meta page shows information about the tech stack. Everything essential is functional.
What I'm not going to do is build features speculatively, create abstractions prematurely, or optimise for scale I don't have. If I need something, I'll build it then. Not before, when it's just theoretical. Not as part of some grand "roadmap" that'll be obsolete in three months anyway.
The Irony Isn't Lost on Me
Writing a blog post about simplifying and starting fresh whilst I spent a week rebuilding many of the same features? Chef's kiss of irony. The difference is I rebuilt them deliberately, not accidentally. Each component earned its place back through necessity, not speculation.
ProfileCard? Needed it for the homepage. StatusCard? Essential for the now page display. Header and Footer? Well, those are kind of non-negotiable for a website. But each one is simpler than its version 9 counterpart. Focussed. Purposeful.
The real test will be in six months when I inevitably want to add something new. Will I fall back into the pattern of "just one more feature" spiralling into complexity? Or will the lessons stick this time?
Now where to point the link to this post...