Barcode-first cataloging
Scan an ISBN or EAN-13. Title metadata resolves asynchronously through a chain of nine providers — BnF, Google Books, Open Library, Library of Congress, K10plus, MusicBrainz, OMDb, TMDb, BDGest — with cover-image download.
mybibli is a self-hosted web app to catalog, locate, and loan your personal library. Barcode-first, multi-media, multi-role — and your data never leaves your network.
Screenshots from the household NAS install that drives the project — same code that's on Docker Hub right now.
Built for collectors who want their library to actually work. Scan a barcode, find a book on a shelf, lend it to a friend — and see what's missing in a series.
Scan an ISBN or EAN-13. Title metadata resolves asynchronously through a chain of nine providers — BnF, Google Books, Open Library, Library of Congress, K10plus, MusicBrainz, OMDb, TMDb, BDGest — with cover-image download.
Books, BD/comics with multi-position omnibus volumes, audio releases, films and series — each typed correctly with the right provider chain selected automatically.
See which volumes are missing in your series at a glance. The dashboard surfaces "series with gaps" alongside Dewey-based browsing and a similar-titles section.
Configurable hierarchy — room → shelf → row, or whatever fits your home. Each shelf gets a barcode; scan the shelf, scan the volume, done.
Borrower CRUD, loan registration, automatic location restoration on return, admin-configurable overdue threshold, per-borrower history.
Anonymous (read-only), Librarian (catalog + loans), Admin (everything). Session inactivity timeout with keep-alive toast. EN / FR language toggle, per-user.
Self-hosted means your home network. So mybibli is built defensively from day one — not as an afterthought.
No unsafe-inline, no unsafe-eval. Every template — server-rendered or HTMX fragment — is audited for inline script and style attributes.
Constant-time compare on every state-changing request. Forms inject the token automatically; HTMX inherits via a small JS listener. Exempt-route allowlist is frozen and policed by tests.
A USB barcode burst that arrives while a modal is open is intercepted at document-capture phase — no leakage into background scan fields, no accidental Cancel/Confirm activation.
No cloud sync, no telemetry, no analytics. Argon2 password hashing, HttpOnly + SameSite cookies, soft-delete with 30-day auto-purge.
Server-rendered HTML, type-checked templates, no SPA framework. The whole UI talks to the server with HTMX over the same routes that serve the pages.
Compiled binary, async tokio runtime, zero-cost middleware tower stack.
Compile-time query checking via the offline cache. Versioned migrations checked into the repo.
Compile-time type-checked Jinja-style templates. Auto HTML-escaping, no surprises.
No build step beyond Tailwind. Server-rendered HTML; small ES modules where the UX needs it.
Cookie-based sessions, per-session CSRF synchronizer token, role-based access control.
English + French today, key-by-key parity enforced by tests. New languages drop in as a single YAML file.
~525 unit, ~95 DB integration, ~160 Playwright E2E across two CI lanes (seeded + wizard).
Rust tests + clippy + sqlx-prepare check, DB integration, Playwright E2E and wizard E2E — gated on every PR.
v1.20.0 — where the labels end: the admin Health tab now shows the last volume number and the last shelf number in use, each with the next free one, so a fresh sheet of barcode labels starts right after the occupied range — trashed items still count, so a printed sticker is never reissued (#489). No migration. Follows v1.19.0 — the security review: three fixes from a review of the 1.18.0 code, and no migration to run. The Trash panel's Restore button now actually restores — it had pointed at an address the application never answered on, so clicking it did nothing at all, quietly, for seventeen releases (#478). The development accounts a fresh install ships with are deleted outright at first boot instead of resting in the Trash with their published passwords intact (#480) — which is exactly what a working Restore button would have handed back. And a cover image can no longer exhaust the server: decoding runs under a fixed budget, so a file that is small on the wire and enormous once decoded is refused rather than taking the whole thing down (#479). Before that, v1.18.0 — management labels applied to titles and copies from one shared vocabulary (#443). Pre-built Docker images on Docker Hub.