Craig Wright
HomeAboutProjectsHome labMusingsContact
© 2026 Craig Wright
← Projects
LiveOpen sourceMedia

Armarium

A self-hosted catalogue for everything I own, physical and digital: music, film, books and games.

Built with FastAPI · SQLAlchemy 2.0 (async) · Alembic · SQLite / PostgreSQL · React 19 · Vite · Tailwind CSS 4 · Zustand · Docker

Visit ArmariumSource on GitHub

What's novel

  • Physical and digital copies of the same title link into one entry with a badge for each format, but only once you've confirmed the match.
  • A barcode scan takes two hops, barcode to product name, then name to the right catalogue, because the film and game databases can't search by barcode.
  • Anything arriving from outside (barcode lookups, uploaded cover art, third-party API responses) is checked where it enters, for size, path tricks and requests to places it shouldn't reach.
  • Plex libraries sync in on a schedule, and anything removed from Plex is removed here too.
  • A household can switch from "everything is shared" to "track who added what" later, with existing items backfilled.

Do I already own this?

I own CDs, a shelf of Blu-rays, a bigger pile of books and a Plex server. I also have a Netflix subscription and a Steam library. None of them talk to each other.

So "do I already own this?" meant checking three or four places. Or, now and then, buying something twice and finding out when I got home.

I wanted one place that knew. It had to be self-hosted: a list of everything I own is exactly the kind of data I don't want in a service that might put its price up, get bought or shut down. Armarium is the result, a library for Music, Films & TV, Books and Games, physical and digital, on hardware I control.

Armarium home screen, light mode, recently added and per-category rows

Two copies, one thing

A lot of what I own exists twice. A Blu-ray and the digital copy that came in the box. A CD and the lossless rip on the server. Cataloguing those as two unrelated items felt wrong the first time I tried it.

So Armarium spots a physical and a digital copy of the same title and offers to link them into one entry, with a badge showing both formats. It never merges them on its own. Two things that share a title aren't always the same thing, and a catalogue that quietly welds them together is one you stop trusting.

Item detail page with metadata and ownership badge

Where is it, actually?

Knowing I own something is only half the question. The other half is which box it went into after the last move.

A flat list of tags would have been easier to build. Instead, locations are a tree: rooms hold shelves, shelves hold boxes, each with its own icon. Digital items get the same idea, with the platform standing in for the shelf.

This is the part most obviously shaped by my own house. It exists because I couldn't find a particular graphic novel after moving, and a tag wasn't going to help.

Locations manager, home modelled as rooms, shelves and boxes

Scan it, don't type it

Nobody is going to type in fifty CD titles. If adding things is a chore, the catalogue is out of date by the second weekend, and then nobody uses it.

So you scan the barcode with a phone or laptop camera, discs and game cartridges alike, and there's a batch mode for emptying a whole shelf in one sitting. Getting that working in Safari on an iPhone took a proper fix, because camera access and barcode decoding behave differently there. And when a code won't scan cleanly, you can always type it in instead of being stuck halfway through.

Add flow: scan a barcode or search by title

The barcode doesn't know what it is

The big film and game databases (TMDB and IGDB) can't look anything up by barcode. So a scan takes two hops. First the barcode goes to a product database to find out what it's called, with a second one as a fallback for very new releases. Only then does Armarium search the right catalogue for that category: TMDB, MusicBrainz, Open Library or IGDB.

The games shelf is where that extra hop paid for itself. Cartridges and discs next to their digital versions, all catalogued, and I didn't type a single title.

Games library, physical and digital copies side by side

Sharing, and a Plex library I already had

Armarium is for a household, so accounts, invites and password resets were there from early on rather than bolted on later.

The bigger job was Plex. I'd spent years building a music and film library there, and I was never going to catalogue it all again by hand. So the admin panel connects to a Plex server and syncs it in, library by library, on a schedule.

The part that mattered most was the unglamorous one: when something disappears from Plex, it disappears from Armarium too. A sync that only ever adds slowly fills up with things you no longer have.

Admin panel for users, permissions and Plex sync

What I got wrong

My first design asked a household to decide up front: is everything shared, or do we track who added what? It sounds like a sensible question in a design document. In real life, nobody wants to answer it before they've even used the thing.

So I built a way to change your mind. Switch modes later, and existing items get their ownership filled in after the fact. It's a small feature, but it changed how I think about data models: people can't really choose one before they've seen how it fits the way they actually live.

Small things

Dark mode could have been a setting saved in the browser, and nobody would have noticed. Instead it's saved against your account, so it follows you from phone to laptop, along with keyboard shortcuts for browsing quickly at a desk. Nobody will ever mention it, which I've decided is fine.

Armarium home screen, dark mode

Where it stands

Armarium is open source and self-hosted, running as a couple of small Docker containers. It installs on a phone like an app and keeps working offline, which matters more than you'd think: standing in a shop with no signal is exactly when "do I already own this?" comes up. armarium.app has the overview, and the code is on GitHub.

I built it in about two weeks in June, pairing with Claude Code, which still surprises me when I write it down. A few years ago, this would have stayed an idea I kept meaning to get round to.

Armarium on mobile, installed as a PWA