Two months ago I was bored and the ESM website was right there, taunting me. Five years of Rails 6 and Vue.js 2 held together with UIkit and determination. It worked fine - thousands of users, no major complaints. But I knew what was lurking in that codebase, and I finally had the time and skills to do something about it.
The original ESM website is a time capsule of decisions that seemed smart in 2019. Need interactivity? Wrap the form in a Vue component. Need that in a modal? UIkit's got you. Now Vue and UIkit are both fighting for the same DOM. The notifications page was peak over-engineering: 668 lines of Vue to handle a form with a live preview. The user alias system tracked three different states per alias because I didn't trust myself to just update things directly.
Every feature became an archaeology dig. The server config form passed seven data attributes to Vue just to boot up. The notification routing mixed Ajax with UI updates with state management because why separate concerns? Open any JavaScript file and you'd find Vue.set() scattered everywhere like breadcrumbs in a forest where I'd gotten lost.
So I rebuilt it. Rails 8, Hotwire, and finally - finally - no more UIKit.
My 668-line notifications monster? It's 95 lines of Stimulus now. You type, it updates the preview. Genius! The server configuration doesn't need Vue at all - it's just a Rails form that does what forms have always done.
The JavaScript folder went from multiple Vue apps requiring manual initialization to Stimulus controllers that just... work. That three-state alias system? Now it's "here's your alias, edit or delete." Click edit, change it, save. No temporary state, no rollback logic, no confusion.
And holy hell, the visual difference. The old site was my attempt at a dark theme - black background, minimal styling, walls of text that made your eyes glaze over. The new one has actual design: cards with proper hierarchy, icons that communicate purpose, empty states that guide instead of abandon, and documentation that looks like someone actually wants you to succeed. The getting started page went from "good luck, here's everything" to an actual onboarding flow.
The real win though? I can maintain this without causing my brain to melt. Adding features doesn't require excavating through framework layers. When something breaks, the error points to actual code, not "somewhere in the reactivity system."
The codebase is boring now - boring in that beautiful way where everything's exactly where you'd expect. Forms are forms. JavaScript sits quietly in the background instead of being the main player. The server handles server things, the client handles client things, and they stay in their lanes.
Two months later, I've got a website that doesn't make me question my life choices every time I open it. The deployment is boring. The maintenance is boring. And after five years of JavaScript framework archaeology, boring feels absolutely incredible.
Turns out the website I wanted to build in 2019 was just Rails all along. Who knew?