Now that the last post is behind me, I want to start getting into the details of a 2016 version of Cushion built in 2024. My original plan was to only refresh the frontend and then rely on the existing API to save time, presumably. That would’ve worked fine, but I also feel like it would’ve still restricted my choices and influenced how I develop this new version. The priority is refreshing the frontend, but that doesn’t mean there isn’t an equally long to-do list of improvements and simplifications I want to make on the backend as well. If I’m “stuck” with a backend that I started writing 10 years ago, I’ll miss out on all the innovations that have happened since then—especially in this new world of frontend-friendly backends.
The existing Cushion is hosted mostly on Heroku—a once-exciting platform that now seems stuck in 2010, when it was acquired by Salesforce. There’s still a lot to love about Heroku, but I’m looking elsewhere this time, in the direction of Vercel. This is a no-brainer for me and not much of a risk because I’ve been using Vercel for pretty much every website I’ve hosted over the past several years. The speed and ease in which you can go from repo to hosted website—with automatic deployments between dev, preview, and prod—is the way the web should be. That said, this will be my first time hosting an actual app with real users on Vercel—beyond a marketing site or a hosted form—so I can’t say I’ve had to troubleshoot something going wrong on Vercel. At the same time, I plan to greatly simplify the backend because it honestly doesn’t need much beyond what can be done in the database. And that’s a perfect segue into our next topic—the database.
Since the start, Cushion has used Postgres as its main database, and I have no regrets with that choice—I’ve always been a relational guy and Postgres only seems to get more and more feature-rich with each and every upgrade. The world around Postgres has gotten pretty interesting over the years, too, with database providers making the new Postgres features more turnkey. This is why I’ve landed on Supabase as my database provider. I have no problem coding a backend, but as soon as I saw that you can use a Postgres database directly from a static frontend and it handles authentication?—I was sold. On top of that, Supabase takes care of the hairiness of Postgres’s realtime features, so you can subscribe to messages, presence, and database changes with a simple client-side listener—sold again. These features unlock so much potential for a modern Cushion, and Supabase makes the features so easily accessible that I can casually experiment with a random idea before feeling like I need to commit.
Now that I’ve touched on the backend—or rather the lack of need for a traditional backend—let’s look at the frontend. Anyone who knows me knows my preference for Vue, so this is another no-brainer. Oddly enough, though, the majority of Cushion’s frontend actually isn’t Vue. When I first started working on Cushion back in 2014, Vue was only starting to make a name for itself. I gave it a shot for a few trips around the block, and while it was fun, exciting and new, Vue didn’t have the maturity I was looking for, so I friend-zoned it. I ended up playing it safe with Angular (v1.2), which shared some similarities with Vue at the time, but was also structured like the MVCS (model, view, controller, service) architectures I knew and loved in the AS3 days. While I found that appealing at the time, I can assure you my interests have since changed. A few years into using Angular, I fell out of love because of its complexity and sluggishness. Fortunately for me, Vue had grown up a lot in those years, seemingly waiting out my relationship with Angular. We’ve been together ever since.
While most of the Vue code that lives in the existing Cushion is Vue 2 with the Options API, I’m using Vue 3 with the Composition API, which is so much more TypeScript-friendly and reads like vanilla JS. When using
<script setup>, any const or function is exposed to the template automatically, so it’s immediately familiar to any straight-JS dev and even more inviting than it was before. I could wax poetic about my love of Vue, but I’ll stop right here and save you all.
When we talk about frontend, we unfortunately still need to talk about bundling. Back in 2014, the initial build scripts for Cushion’s frontend used Gulp—remember Gulp?? Gulp existed well before we had hot module replacement, but we did still had LiveReload to refresh the entire page on save. For several years, I tried to migrate to Webpack, but gave up each time—those who have also tried know what I’ve been through. Then, in 2019, I successfully switched to Vue CLI, which does use Webpack under the hood, but at least provides a wrapper around it to make it less painful. Still, with an Angular frontend that has Vue embedded throughout, there was no way I could get HMR to cooperate.
These days, Vue CLI has been replaced with Vite—an incredibly quick, easy-to-setup, and extensible bundler and dev server from the folks behind Vue. I’ve been using Vite ever since building ProtoPen, my prototyping environment when I worked at Stripe. Like everything Vue-related, it speaks my language, and I just get it from the start. I’ve tried other frameworks over the years, like Nuxt, but the magic that happens behind the scenes always ends up causing problems down the road, and I always find myself needing to troubleshoot magic. To save myself the future headache, I’m keeping it simple, and sticking with straight Vite.
That’s all for the initial setup. We’ll see if these choices stand the test of time.