Skip to content
mybibli
About

A library for the way you actually read.

mybibli started as a one-person itch — keeping track of what's on which shelf, who borrowed which volume, and which BD volumes are still missing in a series I've half-finished. It grew into a small, opinionated tool that tries to be useful without being heavy.

Why a self-hosted app?

Most existing personal-library apps are either spreadsheets, abandoned mobile apps, or cloud SaaS that wants to know your reading habits. None of those fit. A book collection is a private artifact — it tells you a lot about a household — and shouldn't need an internet connection to be useful.

mybibli runs on your hardware. A NAS, a small server, a Raspberry Pi 4 — anything that can host Docker. There is no telemetry, no analytics, no phone-home. Metadata enrichment is the one network call out — to public providers like the BnF, Google Books, OpenLibrary, MusicBrainz — and you can disable any of them in the admin panel.

Who it's for

One household, one library. mybibli is built around shared family use: an admin who set it up, librarians who can catalog and lend, and anonymous browsers (your kids on a tablet) who can search and see what's on a shelf without an account.

It's not designed to scale to thousands of users or to mediate loans between different libraries. If that's what you need, the open-source ILS world (Koha, Evergreen) is mature and excellent.

Design choices that won't change

  • Server-rendered HTML. No SPA, no JSON API as the front-of-house contract. HTMX over the same routes that serve the pages.
  • Compile-time type checking everywhere. Templates are checked by Askama, queries by SQLx's offline cache, and the routing layer is a typed Axum router.
  • Strict Content Security Policy. No inline scripts or styles. Every fragment of HTML — server-side or returned to HTMX — is policed by audit tests that fail the build on regression.
  • No background workers framework. A handful of tokio::spawn tasks for metadata fetch, provider health pings, anonymous-session purge and soft-delete auto-purge — that's it.
  • Two languages, key-by-key parity. EN + FR locales, with a unit test that fails if a key exists in one but not the other.

How it's tested

Roughly 900 tests across three layers: unit tests for pure logic, #[sqlx::test] integration tests that get a fresh database per test, and Playwright end-to-end specs that drive a real browser against the full Docker stack. The CI runs Rust tests + clippy + sqlx-prepare check, DB integration tests, and two Playwright lanes — the seeded-stack suite and a dedicated wizard-E2E lane that boots from an empty database.

Every story merges through a draft PR with green CI. Every epic ends with a retrospective. Every regression gets a test before it gets a fix.

License

mybibli is licensed under the GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later). AGPL was chosen deliberately to keep mybibli and any fork freely modifiable by end users — including forks that are hosted as a service. If you run a modified version, you must offer the corresponding source to your users.

The toolchain

Everything is open source. No vendor lock-in.

Language
Rust 2024 edition
Single statically-linked binary. Memory-safety and a strong type system instead of runtime guards.
Web framework
Axum 0.8
Tokio-based, tower middleware, typed extractors. The middleware order at request time is documented and policed.
Database driver
SQLx 0.8 (MariaDB)
Compile-time query checking via cargo sqlx prepare. Soft delete + optimistic locking applied uniformly.
Templates
Askama 0.15
Jinja-style with auto HTML-escaping, compiled into Rust types — missing or misnamed fields fail at build time.
Frontend
HTMX 2.0 + Tailwind 4
Server-driven UI coordination via custom events. A handful of small ES modules where it's required.
i18n
rust-i18n
YAML files compiled into the binary. EN + FR shipping; extra languages are one new file plus the parity test.
Testing
cargo test + Playwright
~525 unit, ~95 DB integration, ~160 Playwright E2E. Two CI lanes — seeded-stack and a wizard-E2E lane that boots from an empty database.
Hosting
Docker Compose
A small docker-compose.yml: app + MariaDB. Pre-built images on Docker Hub once v1 ships.
CI/CD
GitHub Actions
Four parallel jobs gate every PR. Branch protections require all green before merge.