How my blog works

Musician and software engineer. Former climate scientist. Always a webmaster.

https://robida.net/contact@robida.net
Key Biscayne, FL, 33149, USA

Writing frontend code in 2026 is still very hard.

You need to keep track of application state, and when it changes you need to do API requests to your backend to communicate those changes. You need to send requests with different HTTP methods depending on how the state changes — DELETE, POST, PUT, PATCH, GET. You need to handle retries when something goes wrong. You need to serialize your models to JSON. You need to worry about different HTTP statuses.

No one wants to write APIs. What we want is synchronized state.

My blog has a SQLite database in the backend. When someone visits my blog, they get their own copy of the database, with the records that they can see — public posts that are not in draft mode, as well as any posts they might have authored. That DB is then persisted in the browser (using IndexedDB), and queried using a WASM compiled version of SQLite. The backend DB and the browser DB are kept synchronized by a websocket connection.

(That's the reason behind the cloud icon in the navigation header, in case you're wondering. It shows the status of that synchronization.)

This architecture has so many advantages, and many of them come for free:

  • The frontend doesn't know anything about the network. The Javascript code simply run SQL queries against a local database. There's no serialization, no retries, no HTTP methods nor statuses, no endpoints. The code is much simpler.

  • The frontend is reactive. There's no need to poll for the latest state. If a guest is reading an entry and someone else comments the comment will show up in real time.

  • The blog is offline-first. A guest can load my blog and turn off their wifi. Everything will still work — they can read entries, they can search, and once I've implemented likes and replies they will be able to interact with the entries. Once they're back online, the changes will be synchronized transparently.

  • It's fast. Have I said there are no network requests? Search for something and the results are almost immediate. Interactions are resolved immediately and don't have to wait on server confirmation (though it uses hybrid logical clocks for conflict resolution, and changes could be invalidated later).

This is not my invention — RxDB and PouchDB are examples of frameworks that implement this idea, each one in its own way. My implementation is much simpler, of course, because my needs are much simpler: all I have is a single table where I store h-cards and h-entries.

I'm in love with this architecture, and writing frontend code has never been so fun in the last 10 years. But it has its challenges, as you might expect. The biggest one is that I use microformats with my blog, so everything is built with progressive enhancement in mind — every feature works without Javascript, which doubles the amount of work I have to do.

documentationblog