Technology

Building Mailflo without a JavaScript framework

What if you could build a modern SaaS application without React, Vue, or any JavaScript framework? After years of fighting dependency updates, I took the radical approach of ditching build tools entirely. Here's how HTMX and Vanilla JavaScript proved that simple can still be powerful.

It's quite surprising not to develop a frontend using technologies like React, Svelte, or Vue for building a SaaS-based application these days. When I started the Mailflo project, my main idea was to build a system that is simple and easy to maintain. I quite like SPAs that are interactive and fluid. But maintaining JavaScript with ever-changing packages is tremendously hard for a single developer. In fact, I even tried to build just the Inbox page—where there are lots of interactions and components—with React. Though everything felt good and nice, I had to upgrade the UI in 3 months' time because of some dependency being updated and not supported. So, to keep things simple, I decided to take an extreme approach: no build system at all for the application.

HTMX and Vanilla JavaScript

I was a bit suspicious about starting an application or kind of rewriting the frontend part of the application in HTMX. First and foremost, the way one thinks of the interaction between the components (pages), coming from an SPA background, has to be changed. Basically, you are manipulating the portion of a page with fragments of HTML. To make that efficient, I had to write a simple page to understand how the whole interaction works, including loading certain parts of JavaScript.

In fact, the result was impressive. Of course, there are scenarios where HTMX cannot solve certain parts. For example, an email editor is loaded when the reply/forward button is pressed on the email message. This editor is built using Squire email editor. To initialize the editor, I had to use JavaScript to make this work. I am quite impressed with the way things ended up.

There are scenarios where the click on a link or button should activate/trigger an action on some other part of the page. I had no clue about handling this behavior. After a few minutes into the HTMX documentation, I got to understand Hyperscript.

Magic of _hyperscript

Have you ever gotten frustrated when you couldn't find the documentation for a piece of code that does the magic? For me, it was Hyperscript. Once you get the taste of it, you will simply love it. The behavior of interactive elements like filters and selection states is handled and taken care of by this in the mailbox interface. I would say the complex part in the mailbox UI is handled with simple DSL-like statements. I was scared about ongoing updates initially. Then, I convinced myself that it's definitely not like the management of npm packages and dependencies.

Maybe a bit of compression?

Mailflo is proudly built with Django, PostgreSQL, and Redis. The frontend of the application uses HTMX and Vanilla JavaScript. I wanted to build this like it was the '90s and 2000s. When collecting static files—the process used to collect all the JavaScript and CSS files—esbuild is integrated purely to compress the files. All the code is still visible and clear, but saving a bit of space and served by the whitenoise library.

I don't want to go too technical on my first post about the application and its architecture. There will be following posts that focus on different parts of the application, from the management of DNS to the parsing of an email in the future.