~/fireball1725.ca/articles ← back home
/ 3 min / [librarium][self-hosted][libib][indie]

Why I wrote Librarium

After five or six years and over $100 a year to Libib, the manga sort bug was the one that finally pushed me to build a self-hosted library catalogue for a 1,500-book household.

I paid Libib over $100 a year for five or six years before I built Librarium.

The library has over 1,500 books, manga, & comics in it. Libib was the thing my partner & I had been using since we started cataloguing the collection, & for most of those years it did the basics well enough. The collection kept growing, though, & the parts of Libib that didn’t work started showing.

The bookstore was where it kept biting. I’d be standing in front of a manga series trying to figure out which volumes we already had. Libib has no concept of manga. The volume field is a string, so the volumes come back in lexical order. Volume 1, then 10, 11, 12, then 2. That’s the kind of bug that shows up the first day you put manga data into the app & nobody ever fixed it.

The price tag stopped feeling reasonable around the same time. Paying somebody else over $100 a year for an app that couldn’t sort a manga series in numeric order didn’t sit right.

What was already out there

Before opening an editor I checked what self-hosted alternatives existed. The open-source library software I found was built for lending: catalogues, patrons, due dates, returns. That’s what a public library or a school library needs. A home library with 1,500 books is small by library standards, & the lending workflow is the wrong shape for a household that doesn’t have patrons. Nothing I found in the open-source self-hosted space was built for a home collection.

So I opened a Go project on a weekend.

What it actually is

The first version answered the question that kept biting in the bookstore: which volumes of this series do we have, & which are we missing.

The data model came out of that question. books is the abstract work; book_editions is the manifestation (paperback, hardcover, ebook, audiobook). That split is the FRBR cataloguing model the library world has used for decades, & it solves the manga problem on its own. A volume of a series is a book with its own ISBN & its own edition, sitting inside a series with a numeric position column. Volumes sort the way a human expects.

From there it kept growing. Read state per edition. Per-library RBAC, because not every shelf needs the same access. ISBN scan from the iOS app, with a primary-server picker so the client can talk to more than one Librarium instance at once. Loans, so the household can tell who has the cookbook this week. A separate MCP server that speaks to the API over a personal access token, so I can ask Claude to add a book by ISBN without leaving the chat.

Most of those features came from one of us hitting an annoyance & me deciding it was easier to build the fix than write down the wish.

Three editions, one data model

Once the self-hosted version was running well enough to use every day, the question stopped being whether it solved our problem & became whether it could solve anyone else’s.

The answer is three editions sharing one data model. Self-hosted is the canon: AGPL 3.0, free, runs in Docker, ships today. Lite is an iOS app with a local-only catalogue, no server required. Plus is the hosted version for people who want the product without operating a container. All three speak the same FRBR catalogue & the same sync protocol, so a Lite user who later wants multi-device or shared libraries can move to a server without rebuilding the collection.

I didn’t plan it that way. I built the self-hosted version because we needed it. The tiers came after, because once the self-hosted version was shaped right the rest got easier.

The short version

I was paying over $100 a year for software that couldn’t sort volume 2 before volume 10, & no open-source alternative was built for a 1,500-book household. So I built what we needed, on modern infrastructure, with the features we’d been wishing for.

Everything else followed from there.