The backend is taking shape

A construction worker on a wooden frame, bent over under a blue sky. The scene is framed by dark structural elements.
Photo by Josh Olalde / Unsplash

The first steps are complete for my privacy-minded shopping list project. I’ve built an initial alpha version of the backend server, including all the core features I had in mind—plus a few items from the wishlist.

  • You can sign up via email and authenticate using a magic link.
  • The service is invitation-only. The first user is defined during the setup phase; all other users must be invited by someone already registered.
  • Each user can have one or more shopping lists, and lists can be shared with any other user. Items can be added, edited, or removed from lists.
  • At the moment, items must have a name and can optionally include a list of tags. Shopping lists simply have a name.
GitHub - oliverandrich/shopping-list-server
Contribute to oliverandrich/shopping-list-server development by creating an account on GitHub.

Why Go?

Wait—aren’t you the Python guy? Why Go?

I spent a good chunk of the day thinking about how best to implement the backend service. I had three main options on the table:

  • Python (with nanodjango or FastAPI)
  • Go
  • Rust

And my requirements were:

  • Minimal deployment—ideally a single binary
  • Easy to run on a home server, Raspberry Pi, or any modest device
  • Low memory footprint

Rust was the first to go. I’ve no experience with it, and this side project doesn’t feel like the right time to dive into a new language—especially given the limited spare time I can dedicate to it.

Python would have been my natural first choice, ideally using a PEP 723 script. Unfortunately, nanodjango didn’t behave as expected. FastAPI and SQLAlchemy were off the table due to my dislike of SQLAlchemy. A full Django app could work too, but deploying it without containers doesn’t spark joy—especially for something this lightweight.

Things I’ve always liked about Go:

  • The language is straightforward and easy to pick up
  • Compiling to a single cross-platform binary is effortless
  • You can embed pretty much everything into that binary
  • Great performance and low memory usage

Yes, it’s a bit verbose at times, but that’s a trade-off for its simplicity.

So Go it is. I had to dust off my Go skills a bit, but with the help of Claude, I managed to get the backend up and running after lunch. It’s still very much alpha, with a few rough edges, but I’m quite happy with the current state.

Oliver Andrich

Oliver Andrich

Brewing code, sipping coffee, raising cats and hell (softly).
Lahnstein, Germany