Skip to main content
Open-source digital library

Your library,
open in the browser.

ELVIRA is an open-source digital library: a catalog, a web portal with a built-in reader, and Readium LCP lending. The Slovak University of Technology keeps its publications in it, and any university can run its own.

In production at the Slovak University of Technology and the Catholic University in Ružomberok. Free and open source.

elvira.stuba.sk
The ELVIRA portal: a grid of publication covers with a search bar

ELVIRA and EvilFlowers

You will see both names on this site. ELVIRA is the platform you run and readers use. EvilFlowers is the name of its catalog server and of the GitHub organization that holds the code, so most repositories carry it.

The platform

ELVIRA

The whole digital library: the catalog, the portal readers sign in to, the PDF reader, lending and the workers that process publications. STU runs it at elvira.stuba.sk, and the Catholic University in Ružomberok runs its own instance.

The catalog and the code

EvilFlowers

EvilFlowersCatalog is the catalog server at the centre of ELVIRA. It started as a side project before ELVIRA existed and kept its name. All ELVIRA code lives in the EvilFlowersCatalog organization on GitHub.

Find it, read it, borrow it, cite it

Everything below runs in production today.

Read in the browser

Every PDF opens in the built-in reader. Search inside the text, page through thumbnails, highlight and take notes. Nothing to install.

Borrow protected titles

Lend e-books with Readium LCP, the open DRM public libraries use. Readers borrow, renew, return and join a waiting list when all copies are out.

Use any e-reader app

Every catalog is also an OPDS 1.2 and 2.0 feed. Add it to Thorium or another OPDS app and browse, borrow and read there.

Cite and share

Copy a citation as BibTeX, BibLaTeX or RIS. Share a page range instead of the whole file.

Many libraries, one install

One server hosts separate catalogs, each with its own publications and permissions. Sign in with local accounts or your university’s LDAP.

An API for everything

Whatever the portal can do, a script can do over the documented REST API. AI agents connect over the Model Context Protocol.

Built for reading papers and textbooks

Every publication opens in the same reader, at the page where you stopped. Search the full text, highlight and annotate, switch to dark mode and copy a citation without leaving the tab. The reader is a standalone npm package, so you can embed it in your own app.

  • Full-text search inside the document
  • Highlights, notes and page-range sharing
  • Citation export, and download where the license allows
elvira.stuba.sk/reader
The ELVIRA reader with a book open and page thumbnails along the bottom

What we are building now

These run in our development environment and are moving to production. The code is already public. What changed since May.

Search by passage

In development

Search returns the paragraph that matches, with the hit highlighted. It matches the words of a query and its meaning, so a Slovak question can find an English paragraph.

Structure from every PDF

In development

Extraction workers split each publication into paragraphs and sentences, crop its figures and tables, and turn its formulas into LaTeX.

An assistant that cites

In development

Ask a question about the collection and get an answer built from its passages, with a link to each one it used.

Printed books, digitized

In development

The digitalizer turns scans into an OCR’d PDF, a PDF/A archival copy and an EPUB, and publishes them to the catalog.

One catalog, everything around it

A catalog server holds the records and serves them over standard protocols. The portal, e-reader apps, AI agents and the digitalizer are its clients. Encryption and extraction run as separate workers.

ELVIRA component diagramThe web portal, OPDS reading apps, AI agents and the books digitalizer all talk to EvilFlowersCatalog through its HTTP interfaces. The catalog stores data in PostgreSQL, sends encryption tasks to the lcpencrypt worker and extraction tasks to the analyzer through Redis, and proxies the Readium LCP server. Extraction workers post their results back to the catalog.elvira-portal: Readers and librarians use the portal to search the catalog, borrow LCP titles, manage loans and reservations, keep a shelf and read PDFs in the built-in reader. It is a React and Vite app in Slovak and English, themed per institution at build time.elvira-portalReact web appEvilFlowersViewer: EvilFlowersViewer is the PDF reader inside the portal. It is built on pdf.js, published on npm, and supports search inside the document, highlights and notes, page-range sharing and citation export.EvilFlowersViewerPDF reader, npm packageReading appsThorium, any OPDS clientAI agentsany MCP clientbooks-digitalizer: The digitalizer takes TIFF scans of printed books, cleans the pages and runs Slovak OCR. For each book it produces a fast distribution PDF, a PDF/A-2b archival master and an EPUB, then publishes the book to the catalog. It runs as a batch job or as a web studio for reviewing books page by page.books-digitalizerscans → PDF/A, EPUBREST, files, chatloanscatalog feedsloan statustools, API keypublish, API keyEvilFlowersCatalog: EvilFlowersCatalog is the server every other component talks to. This Django application stores publications, users and loans, serves them over OPDS 1.2, OPDS 2.0 and a REST API, and can host many separate catalogs in one install.EvilFlowersCatalogDjango + Celery. Catalogs, publications, users, loans, annotations.One install hosts many separate libraries./api/v1 · /data/v1 · /assistant/v1/readium/v1/opds/v1.2 · /opds/v2/mcp/v1/api/v1/extraction/v1lcpencrypt-worker: This Celery worker encrypts each file the catalog marks for lending with Readium’s lcpencrypt, registers it with the LCP server and reports the result back to the catalog.lcpencrypt-workerencrypts filesreadium-lcp-server: This repository packages the upstream Readium LCP server for our deployments. The server issues licenses and the License Status Documents reading apps use to renew and return loans. Only the catalog talks to it.readium-lcp-serverlicenses, statusregisters encrypted filesPostgreSQL 18: This is the PostgreSQL 18 image the catalog runs on, with pgvector for embeddings, pg_search for BM25 ranking, and pg_cron and pgaudit for operations.PostgreSQL 18pgvector, pg_searchRedistask queueFileslocal disk or any S3 storeanalyzer: The analyzer starts each extraction run. It opens the PDF, finds the page layout with Docling, and sends paragraphs and tables to the text service, figures to the image service and formulas to the equation service.analyzerpage layouttext: The text service extracts paragraphs and their sentences with positions on the page, and embeds each paragraph so similar passages can be found. It also converts tables to Markdown and embeds the queries for passage search.textparagraphsimage: The image service crops each figure out of the page so readers can browse a publication’s figures. Generated captions are optional and off by default.imagefiguresequation: The equation service crops each formula and reads it back as LaTeX with a LaTeX-OCR model, so equations can be searched and copied.equationLaTeXencryption tasklicenses, statusSQLCelery tasksextraction taskresultsIn the reader’s browserLending · Readium LCPStorageExtraction · in development
In production In development Library Not part of the projectClick a box to open its repository.

Reasons to run it

Open standards, no lock-in

OPDS for catalogs, Readium LCP for lending, OpenAPI for the API. Reader apps you already use work with it, and your data leaves in formats other software reads.

Open source

The code is public on GitHub under permissive licenses. Read it, run it, change it, and send your changes back if you like.

In daily use

It serves the whole Slovak University of Technology, and the Catholic University in Ružomberok runs its own instance.

Your servers, your data

It runs on your own hardware: PostgreSQL for records, a local disk or any S3 store for files. Nothing is sent to a vendor.

Made for academic texts

Citation export, annotations, page-range sharing and Dataverse research datasets are built in.

A small core

The catalog handles records, permissions and loans. OCR, AI and encryption run as separate workers you add when you need them.

Pick where you start

Read at STU

Go to elvira.stuba.sk and sign in with your university account. Search, open a book, borrow it.

Reader guide →

Use your own app

Add the catalog’s OPDS feed to Thorium Reader or another OPDS app to browse and borrow outside the browser.

Connect an app →

Run your own

The catalog starts with Docker Compose and is ready on localhost:8000:

git clone https://github.com/EvilFlowersCatalog/EvilFlowersCatalog.git
cd EvilFlowersCatalog
docker compose up -d --build django
docker compose exec django python3 manage.py setup
docker compose exec django python3 manage.py createsuperuser
Full quickstart, with the portal →

Could your library run on this?

Start with the quickstart, or write to us. We help faculties and universities set it up.

In production at
Slovak University of TechnologyCatholic University in Ružomberok