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::spawntasks 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.