Grimmory is an independent community fork of Booklore. https://grimmory.org
  • Java 52.2%
  • TypeScript 30.1%
  • HTML 8.7%
  • SCSS 6.4%
  • JavaScript 2.2%
  • Other 0.2%
Find a file
Jeremy Bush cfaa082c6b
Some checks failed
notify-discord-release-notes.yml / Merge pull request 'feat(ui): command palette uses server-side book search' (#4) from bd-grimmory-n55.6 into develop (push) Failing after 0s
CodeQL / Analyze (actions) (push) Failing after 3s
CI - Validate / Upload Event File (push) Failing after 2s
CodeQL / Analyze (java-kotlin) (push) Failing after 4s
CodeQL / Analyze (javascript-typescript) (push) Failing after 3s
CI - Validate / Check for DB Migrations (push) Successful in 14s
CI - Validate / Flyway DB Migration Preview (push) Has been skipped
CI - Validate / Flyway Migration Check (push) Successful in 0s
CI - Validate / Backend Tests (push) Failing after 2s
CI - Validate / Frontend Tests (push) Failing after 2s
CI - Validate / Test Suite (push) Failing after 0s
CI - Validate / Packaging Smoke Test (push) Has been skipped
CI - Frontend Quality Thresholds / Frontend Lint Threshold Check (push) Failing after 2m12s
Merge pull request 'feat(ui): command palette uses server-side book search' (#4) from bd-grimmory-n55.6 into develop
Reviewed-on: #4
2026-05-11 00:53:44 +00:00
.beads chore: complete bd init setup and add .claude orchestration assets 2026-05-10 19:48:11 -05:00
.claude chore: complete bd init setup and add .claude orchestration assets 2026-05-10 19:48:11 -05:00
.github ci: use last release as nightly base tag (#1226) 2026-05-09 15:07:38 -04:00
assets feat(ui): New sidebar & search UI (#831) 2026-05-04 09:46:48 +01:00
backend fix(api): batch-fetch comicMetadata to avoid N+1 on book iteration 2026-05-10 14:21:46 -05:00
deploy feat(deploy): add healthchecks to docker, docker compose, podman quadlet, and helm chart (#1137) 2026-05-07 20:50:53 -04:00
docs ci(docker): rotate Docker Hub auth secrets for token-based publishing (#1179) 2026-05-07 03:08:21 -04:00
frontend feat(ui): command palette uses server-side book search 2026-05-10 14:29:30 -05:00
packaging/docker fix(entrypoint): ensure books directory exists and is writable by the target user (#119) 2026-04-22 17:26:34 -04:00
scripts refactor(frontend): repoint repo tooling to the frontend path 2026-04-22 17:26:39 -04:00
tools feat(tools): add perf measurement script for books API 2026-05-10 19:10:22 -05:00
.coderabbit.yaml chore(coderabbit): add better review configuration with Java 25 and Angular 21 standards (#996) 2026-04-29 23:54:38 +02:00
.dockerignore chore: rename springboot app folder to backend (#752) 2026-04-22 17:27:44 -04:00
.gitattributes add: .gitattributes for building on windows (#1422) 2025-10-23 13:26:00 -06:00
.gitignore chore: complete bd init setup and add .claude orchestration assets 2026-05-10 19:48:11 -05:00
.nvmrc chore(nvm): moved .nvmrc file to the repository root (#237) 2026-04-22 17:26:52 -04:00
.yarnrc.yml build(yarn): migrate frontend and release tooling to yarn 4 2026-04-22 17:26:40 -04:00
AGENTS.md chore: complete bd init setup and add .claude orchestration assets 2026-05-10 19:48:11 -05:00
AI_POLICY.md docs: add AI usage policy for contributors (#547) 2026-04-22 17:27:37 -04:00
CLAUDE.md Symlink CLAUDE.md 2026-04-22 17:26:52 -04:00
CODE_OF_CONDUCT.md docs: add code of conduct (#546) 2026-04-22 17:27:36 -04:00
CONTRIBUTING.md chore: rename springboot app folder to backend (#752) 2026-04-22 17:27:44 -04:00
dev.docker-compose.yml refactor(docker): consolidate JVM options into JAVA_TOOL_OPTIONS (#1074) 2026-05-06 09:28:50 +02:00
DEVELOPMENT.md chore: rename springboot app folder to backend (#752) 2026-04-22 17:27:44 -04:00
Dockerfile feat(deploy): add healthchecks to docker, docker compose, podman quadlet, and helm chart (#1137) 2026-05-07 20:50:53 -04:00
GOVERNANCE.md docs(governance): add project rep (#1218) 2026-05-08 18:02:55 -04:00
Justfile feat(tools): add perf measurement script for books API 2026-05-10 19:10:22 -05:00
LICENSE Change licensing to GNU Affero General Public License v3.0 (AGPL-3.0) 2026-01-20 17:26:56 -07:00
mise.toml feat(devex): add a unified just command surface 2026-04-22 17:26:35 -04:00
README.md docs: Fix Link to Quick Start Guide (#1177) 2026-05-07 08:22:23 +02:00
SECURITY.md docs(security): update security policy with reporting guidelines and hints to supported versions (#76) 2026-04-22 17:26:31 -04:00
unraid.xml chore(unraid): sync unraid template with README (#417) 2026-04-22 17:27:07 -04:00

Note

Grimmory is an independent community fork of Booklore.

Grimmory

Grimmory is a self-hosted digital library for people who take their reading seriously.

Release License Docker Pulls Discord

Documentation · Quick Start · Discord · Releases


Features

Feature Description
Smart Shelves Custom and dynamic shelves with rule-based filtering, tagging, and full-text search
Metadata Lookup Covers, descriptions, reviews, and ratings pulled from Google Books, Open Library, and Amazon, all editable
Built-in Reader Read PDFs, EPUBs, and comics in the browser with annotations, highlights, and reading progress tracking
Device Sync Connect a Kobo, use any OPDS-compatible app, or sync progress with KOReader
Multi-User Separate shelves, progress, and preferences per user with local or OIDC authentication
BookDrop Drop files into a watched folder and Grimmory detects, enriches, and queues them for import automatically
One-Click Sharing Send any book to a Kindle, an email address, or another user directly from the interface

Supported Formats

Category Formats
eBooks EPUB, MOBI, AZW, AZW3, FB2
Documents PDF
Comics CBZ, CBR, CB7
Audiobooks M4B, M4A, MP3, OPUS

Quick Start

Tip

For OIDC setup, advanced configuration, or upgrade guides, see the full documentation.

Requirements: Docker and Docker Compose.

Image Repositories
Registry Image
Docker Hub grimmory/grimmory
GitHub Container Registry ghcr.io/grimmory-tools/grimmory

Step 1: Environment Configuration

Create a .env file:

# Application
APP_USER_ID=1000
APP_GROUP_ID=1000
TZ=Etc/UTC

# Database
DATABASE_URL=jdbc:mariadb://mariadb:3306/grimmory
DB_USER=grimmory
DB_PASSWORD=ChangeMe_Grimmory_2025!

# Optional: enable API docs + export OpenAPI JSON (defaults to false)
API_DOCS_ENABLED=false

# Storage: LOCAL (default) or NETWORK (disables file operations; see Network Storage section)
DISK_TYPE=LOCAL

# MariaDB
DB_USER_ID=1000
DB_GROUP_ID=1000
MYSQL_ROOT_PASSWORD=ChangeMe_MariaDBRoot_2025!
MYSQL_DATABASE=grimmory

Step 2: Docker Compose

Stable images are published from semantic-release tags on main as vX.Y.Z plus latest. Nightly images are built from develop and tagged nightly.

Note

Migrating from an existing Booklore container? You can keep your current service name, container_name, database name and user, ports, and mounted volumes the same. Replace only the image: line with grimmory/grimmory:<tag> or ghcr.io/grimmory-tools/grimmory:<tag>.

services:
  booklore:
    image: grimmory/grimmory:v2.2.1

Create a docker-compose.yml or copy and adapt deploy/compose/docker-compose.yml:

services:
  grimmory:
    image: grimmory/grimmory:latest
    # Convenience tag:
    # image: grimmory/grimmory:<release-version>
    # Alternative: ghcr.io/grimmory-tools/grimmory:<release-version>
    # To build from source instead: comment out 'image' and uncomment below
    # build: .
    container_name: grimmory
    environment:
      - USER_ID=${APP_USER_ID}
      - GROUP_ID=${APP_GROUP_ID}
      - TZ=${TZ}
      - DATABASE_URL=${DATABASE_URL}
      - DATABASE_USERNAME=${DB_USER}
      - DATABASE_PASSWORD=${DB_PASSWORD}
      - API_DOCS_ENABLED=${API_DOCS_ENABLED}
      - DISK_TYPE=${DISK_TYPE}
    depends_on:
      mariadb:
        condition: service_healthy
    ports:
      - "6060:6060"
    volumes:
      - ./data:/app/data
      - ./books:/books
      - ./bookdrop:/bookdrop
    healthcheck:
      test: wget -q -O - http://localhost:6060/api/v1/healthcheck
      interval: 60s
      retries: 5
      start_period: 60s
      timeout: 10s
    restart: unless-stopped

  mariadb:
    image: lscr.io/linuxserver/mariadb:11.4.5
    environment:
      - PUID=${DB_USER_ID}
      - PGID=${DB_GROUP_ID}
      - TZ=${TZ}
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
      - MYSQL_DATABASE=${MYSQL_DATABASE}
      - MYSQL_USER=${DB_USER}
      - MYSQL_PASSWORD=${DB_PASSWORD}
    volumes:
      - ./mariadb/config:/config
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "mariadb-admin", "ping", "-h", "localhost"]
      interval: 5s
      timeout: 5s
      retries: 10

Step 3: Launch

docker compose up -d

Open http://localhost:6060, create your admin account, and start building your library.

Additional deployment examples:


Developer Surfaces

Contributor workflow, PR policy, and release semantics live in CONTRIBUTING.md.

General purpose development guidelines live in DEVELOPMENT.md. Component-specific implementation guidance lives in:

The root Justfile is the primary local command surface and mirrors the folder-local backend/Justfile and frontend/Justfile entrypoints.

just               # Show root + api + ui recipes
just test          # Run backend and frontend tests
just api test      # Run backend tests only
just ui dev        # Start the frontend dev server

API Reference Docs

When enabled via API_DOCS_ENABLED, API reference documentation is available as both an openapi.json and as publicly accessible docs. The endpoints are:

  • API reference docs are available at http://localhost:6060/api/docs
  • OpenAPI JSON is available at http://localhost:6060/api/openapi.json

BookDrop

Drop book files into a watched folder. Grimmory picks them up, pulls metadata, and queues them for your review.

graph LR
    A[Drop Files] --> B[Auto-Detect]
    B --> C[Extract Metadata]
    C --> D[Review and Import]
Step What Happens
1. Watch Grimmory monitors the BookDrop folder continuously
2. Detect New files are picked up and parsed automatically
3. Enrich Metadata is fetched from Google Books and Open Library
4. Import You review, adjust if needed, and add to your library

Mount the volume in docker-compose.yml:

volumes:
  - ./bookdrop:/bookdrop

Network Storage

Set DISK_TYPE=NETWORK in your .env to run Grimmory against a network-mounted file system (NFS, SMB, etc.). In this mode, direct file operations (delete, move, rename from the UI) are disabled to avoid destructive changes on shared mounts. All other features — reading, metadata, sync — remain fully functional.


Community and Support

Channel
Report a bug Open an issue
Request a feature Open an issue
Contribute Contributing Guide
Join the discussion Discord Server

Warning

Before opening a pull request, open an issue first and get maintainer approval. Pull requests without a linked issue, without screenshots or video proof, or without pasted test output will be closed. All code must follow the project backend and frontend conventions. AI-assisted contributions are welcome, but you must run, test, and understand every line you submit. See the Contributing Guide for full details.


License

Distributed under the terms of the AGPL-3.0 License.