Skip to content
Self-hosted · AGPL-3.0-only

You are holding a book in a bookshop. Do you already own it?

Librero is a small, self-hosted catalogue of the books you own. Scan the barcode and it answers in seconds — including which edition is already on your shelf.

$docker compose up -d

Runs on a Raspberry Pi, a NAS or a small VPS. One directory to back up.

Scan9780441013593
You already own this

Dune · Frank Herbert
Ace, 2010 paperback

Shelf: Living room, B3

Placeholder — scan verdict screen, 1170×2532

You already own this

Exact ISBN match. Librero names the shelf your copy is on, so you can put this one back.

1 copyRead · ★★★★☆Lent to Ana

Four verdicts, no ambiguity. The scanner and the answer are the product; the catalogue is the supporting cast.

The four verdicts

One scan, one of four answers

Everything else in the application exists to keep these four accurate.

You already own this

Exact ISBN match and at least one copy on your shelf.

Put it back — here is the shelf.

You own a different edition

Same book, different printing. Librero lists the editions you hold.

A real decision, not an accident.

On your wishlist

You recorded wanting this book, and you do not own it yet.

Buy it.

Not on your shelf

No match anywhere in your library or wishlist.

Add it in one tap, or wishlist it.

How it works

Four steps, one hand, a few seconds

  1. 01Point the camera

    Open Librero, aim at the barcode. Or type a title.

  2. 02It matches the ISBN

    Against your shelf first, then your wishlist.

  3. 03You get the verdict

    With the edition you hold and the shelf it sits on.

  4. 04Add, wishlist or walk away

    One tap, then back to browsing the shop.

Features

What is in the box

Catalogue

Bookstore checkScan an ISBN barcode with the phone camera, or type a title.
Editions and copies, modelled honestlyWork → Edition → Copy. Two identical paperbacks are one edition, quantity two.
Physical and digitalRecord a shelf location, or upload the EPUB/PDF and download it again when signed in.
Metadata for freeOpen Library first, Google Books to fill the gaps. No API key required.
Full-text searchTitle, author, series and ISBN, with diacritic folding.

Reading

Reading statusWhere you are with each book.
Ratings and notesPer book, private to your household.
WishlistSo a bookshop lookup can say "you wanted this".
LoansLend a copy out and see what is currently out of the house.

Your data

CSV import/exportGoodreads exports included. Export re-imports losslessly.
One-directory backupOne SQLite file and one uploads directory. Copy the folder, you are done.
AccountsOne shared household library; administrators also manage users.
Dark and light themesBoth first-class, on every screen.
Editions, explained

“Do I own this book?” and “do I own this book?”

They are different questions, and the second is the one that matters at the till. Librero keeps a Work, its Editions and the Copies you actually own as three separate things — which is why it can tell you that the hardcover in your hand is not the paperback at home.

Work
DuneFrank Herbert
Editions
1965 hardcoverChilton · 0441172717
2021 tie-in paperbackAce · 9780441013593
Copies
×1 · Living room, B3Owned
×2 · Study, shelf 1EPUB uploaded
Screenshots

What you actually look at

public/screenshots/library-table.png
2560×1600
Library table. Every edition you own, filterable and sortable, with copy counts.
public/screenshots/book-detail.png
2560×1600
Book detail. One work, its editions, and the copies you hold of each.
public/screenshots/wishlist.png
2560×1600
Wishlist. Books you want, ready for the next bookshop lookup.
public/screenshots/import-wizard.png
2560×1600
Import wizard. Map a Goodreads or Librero CSV column by column before anything is written.

Placeholder frames — drop real captures into public/screenshots/ and they replace these one for one.

Self-hosting

Everything you need to run it

Requirements: Docker and Docker Compose. Runs comfortably on a Raspberry Pi, a NAS or a small VPS.

Docker quick start
cp .env.example .env
# Fill in SESSION_SECRET and ADMIN_PASSWORD:
openssl rand -base64 48        # -> SESSION_SECRET

docker compose up -d

Then open https://localhost (or your LIBRERO_HOSTNAME), sign in with ADMIN_USERNAME and ADMIN_PASSWORD, and choose a real password when asked — you are prompted immediately.

HTTPS is not optional if you want the scanner

Browsers only grant camera access on a secure origin, so a phone talking to http://… cannot scan. The bundled Caddy service handles this automatically: a real hostname in LIBRERO_HOSTNAME gets a Let’s Encrypt certificate, and the default gets a local one. localhost counts as a secure origin, so development works on the machine’s own webcam.

Environment variables

VariableRequiredNotes
SESSION_SECRETyes≥32 characters. The container refuses to start without it. Changing it signs everyone out.
ADMIN_PASSWORDfirst runTemporary; the holder must change it at first sign-in.
ADMIN_USERNAMEnoDefault admin. Used only when the users table is empty.
LIBRERO_HOSTNAMEnoCaddy's site address. A real domain gets Let's Encrypt automatically.
LIBRERO_DATA_DIRno./data locally, /data in Docker.
LIBRERO_CONTACT_EMAILrecommendedSent to Open Library so they can reach you about traffic, per their API policy.
GOOGLE_BOOKS_API_KEYnoRaises quota only; lookups work without it.
MAX_UPLOAD_MBnoDefault 100.

Backup

LIBRERO_DATA_DIR holds librero.db and uploads/ (covers and ebooks) and nothing else. Back up that one directory and you have backed up the whole application; there is no other state.

Back up everything
tar czf librero-backup.tar.gz ./data

What Librero is not

Being explicit here is a feature. It is how you decide quickly.

  • Not an integrated library system: no patrons, reservations or fines.
  • Not a reading app: uploaded EPUBs are downloaded, not read in the browser.
  • No social features: no public reviews, friends or feeds.
  • Not public: every page and every file requires a session. There is no anonymous view of anyone's library.
  • Built for hundreds to a few thousand books. Above that SQLite still copes, but you are probably running a library, not a bookshelf.
Under the hood

What you are running

ApplicationNext.js 16 (App Router) + React 19 + TypeScript
DatabaseSQLite via better-sqlite3, Drizzle ORM with checked-in migrations
SearchSQLite FTS5
InterfaceTailwind v4 + shadcn/ui
ValidationZod
Authargon2id password hashing, signed JWT session cookie
TestsVitest and Playwright
DeploymentDocker + Caddy
FAQ

Questions worth asking first

Shelf lookup does — it only touches your own database. Metadata lookup for a new book needs the network, because that comes from Open Library and Google Books.