Sam Chada

BLD-001·Building

Why I'm Building a Library System From Scratch

Twenty years of watching libraries depend on software they can't shape. l/30 is what happens when you stop waiting.

I'm building a library management system. From scratch. Open source, AGPL-licensed, designed for the library that exists in 2030 rather than the one that existed in 2003.

Why

The problem was never bad software written by bad people. It's who owns the software. OverDrive, where I worked from 2008 to 2011, is owned by KKR. The other big names in the catalog and circulation business have churned through private equity and corporate consolidation on the same logic: SirsiDynix now sits under Constellation Software, Ex Libris and Innovative under Clarivate. That ownership comes with annual contract cycles, roadmaps set by the largest accounts, and migration costs high enough that switching feels impossible even when the fit is wrong. After twenty years of watching libraries depend on software they couldn't shape, I stopped waiting for someone else to build the alternative.

Libraries deserve a system they can actually own. Not license with exit penalties, own. When your ILS vendor gets acquired and the roadmap changes, you should have an option that doesn't require a six-figure migration.

What it actually is

l/30 is a full-stack library management system:

  • Backend: Python/FastAPI with PostgreSQL and Redis
  • Frontend: React/TypeScript
  • Search: pgvector for semantic search alongside traditional keyword
  • Deployment: Docker Compose, designed to run on modest hardware

It's live at l30.org. Real containers, real data, approaching customer-testing readiness.

What's built

The scope is wider than I planned, which is its own thing to manage:

Core ILS: Circulation (checkout, holds, renewals), cataloging with MARC and BIBFRAME support, patron management, inventory tracking, acquisitions.

The stuff that usually costs extra: A learning management system with courses and certificates. Reading programs with gamification. Makerspace equipment tracking. Home delivery logistics for homebound patrons. Event management. A blog module.

The stuff most ILS platforms don't do at all: Fair scheduling that prevents staff burnout. School partnership tracking with impact reporting. Emergency operations with offline mode and paper backup procedures. Semantic search using vector embeddings. Equity-focused cohort tools for literacy matching and immigrant services.

Infrastructure: Dual audit logging (operational + tamper-evident HMAC), CIPA compliance tooling, Z39.50 support, EDI for vendor ordering, board and strategic planning modules.

The surface area is large, 274 API endpoints and 400+ frontend pages, which is both a feature and a maintenance commitment I think about every week. It runs in production behind nginx with proper caching and health checks.

Decisions I made early

AGPL, not MIT. If someone takes this code and builds a proprietary SaaS on it, the license requires them to share their modifications. MIT would let a vendor fork it, add features, and sell it back to libraries as closed-source. AGPL prevents that while keeping it free for libraries to use, modify, and host however they want.

PostgreSQL with pgvector. Traditional ILS search is keyword-based. A patron searching for "books about grief after losing a parent" returns nothing useful because no catalog record contains that phrase. Vector search understands semantic meaning. Both approaches run side by side. You get the precision of keyword search and the flexibility of semantic search.

Python/FastAPI was the language and framework choice. Libraries that want to self-host need to maintain this, and Python has a larger talent pool among library technologists than Node does. FastAPI gives you automatic API documentation, type checking, and async support without the heaviness of Django.

For deployment I went with Docker Compose rather than Kubernetes. The target deployment is a library running this on a single server or a small VPS. Compose gives you container isolation, easy updates, and reproducible deployments without requiring a DevOps team.

BIBFRAME is in the data model from day one rather than retrofitted. Most ILS platforms are layering linked data onto MARC-era architectures. l/30 supports both, so when the transition accelerates, libraries running l/30 won't need a migration.

What surprised me

The scope of a real ILS is enormous. I knew this intellectually. Living it is different. A library isn't just circulation and cataloging. It's event rooms and 3D printers and homebound delivery and volunteer coordination and board reports and emergency procedures. Every one of those is a module that needs designing, building, and testing.

Equity features aren't add-ons. When you design a system from scratch, you can build equity into the architecture rather than bolting it on. Fair scheduling isn't a plugin. It's how the scheduling system works. Literacy-level matching isn't a separate product. It's a property of how patron records relate to collection records.

Offline resilience matters more than I expected. Rural libraries lose internet. Storms happen. The system needs to degrade gracefully, not catastrophically. Paper backup procedures and data sync aren't exciting features, but they're the difference between "the system is down" and "we can still serve patrons."

What's next

Customer testing. Real librarians using the system, finding the gaps between what I built and what they need. That feedback loop is everything. No amount of architectural planning substitutes for watching someone try to check out a book and getting confused by a button placement.

If you're a librarian interested in what this looks like, the system is live.

The code is open. The architecture is documented. The roadmap comes from libraries and the people who work in them, not from whoever buys the vendor next.

Filed · BLD-001 · 2026.05.10