Skip to content

vavallee/bindery

Repository files navigation

Bindery

Bindery

Automated book download manager for Usenet & Torrents
Monitor authors. Search indexers. Download. Organize. Done.

CI codecov Release Docker Go Report Card License Discord


Bindery — Author detail page with monitored books

Bindery — Authors overview with monitoring badges

Bindery — Books library grid view

Mobile-friendly

Books — mobile     Authors — mobile     Author detail — mobile


Why Bindery?

Readarr is dead. The official project was archived in June 2025 and its metadata backend (api.bookinfo.club) is permanently offline. Community forks rely on fragile Goodreads scrapers that break regularly. There was no reliable, open-source tool for automated book management on Usenet.

Bindery is the clean-room replacement. Built from scratch in Go with a modern React UI, Bindery uses only stable, documented public APIs for book metadata. No scraping. No dead backends. No fragile dependencies.

Features

Library management

  • Author monitoring via OpenLibrary's author-works endpoint, with per-book monitor toggles and a wanted → downloading → downloaded → imported workflow.
  • Dual-format books — each title holds an ebook and an audiobook in independent slots, with separate search, grab, and import pipelines, and the audiobook side moves multi-part .m4b / .mp3 folders as one unit.
  • Series support with position tracking, edition tracking (format / ISBN / publisher / page count), Calendar view of upcoming releases, and multiple library roots.
  • Library scan with four-tier matching: ASIN → title + author → series name + position → fuzzy title. Honours librarian sort-suffix form (Title, The) and series-annotated filenames ([Mistborn, Book 1]).
  • Author aliases (RR Haywood / R.R. Haywood / R R Haywood merge into one canonical row), and metadata re-bind to correct a wrong match without delete-and-re-add.

Search & downloads

  • Newznab + Torznab indexers queried in parallel, deduplicated, then composite-ranked by format quality, edition tags (RETAIL / UNABRIDGED / ABRIDGED), year match, grab count, size, and ISBN exact-match bonus.
  • Smart matching — four-tier query fallback (t=booksurname+titleauthor+title → title), word-boundary keyword matching, contiguous-phrase requirement for multi-word titles, dual-author-anchor for ambiguous short titles, subtitle-aware (Title: Subtitle).
  • SABnzbd, NZBGet, qBittorrent, Transmission, Deluge — with Use SSL and URL Base for reverse-proxy subpaths.
  • Auto-grab sweep every 12h, immediate search on add or wanted flip, plus interactive per-book search and "Search all wanted" per author. Global kill-switch pauses auto-grab without losing your monitored list.
  • Quality profiles (EPUB / MOBI / AZW3 / PDF), language filter, regex-based custom formats, delay profiles, blocklist (consulted on every search; one-click add from History), and failure visibility in Queue and History.

Import & organize

  • Completed downloads matched by NZO ID and placed in the library with configurable naming. Modes: Move (default), Copy (keep source for seeding), Hardlink (zero extra disk; same filesystem required).
  • Naming tokens — {Author}, {SortAuthor}, {Title}, {Year}, {Series}, {SeriesNumber}, {ext} — collapse cleanly for non-series books.
  • Cross-filesystem-safe moves: atomic rename when possible, copy + verify + delete for NFS / separate volumes. Full grab / import / failure history per book.
  • Calibre integration in three modes: calibredb CLI hook on import, Bindery Bridge plugin (cross-container), or direct read of an existing Calibre library's metadata.db as Bindery's catalogue.

Metadata sources — all stable, documented, public APIs. No Goodreads scraping.

Source Auth Used for
OpenLibrary None Primary: authors, books, editions, covers, ISBN
Google Books API key (free) Enrichment: descriptions, ratings
Hardcover.app None (public GraphQL) Enrichment: community ratings, series, wishlist
DNB None (public SRU) German-language descriptions, language, year, publisher; can be promoted to primary
Audnex None Audiobook narrator, duration, cover by ASIN
Audible None Supplemental audiobook author lookup — pulls ASINs OL/Hardcover miss

Cover images are fetched and cached server-side under <dataDir>/image-cache/ (30-day TTL). Every imageURL is rewritten to /api/v1/images?url=... before leaving the server — the browser never contacts third-party image hosts directly.

Discover — personalised recommendations on the Discover page from multiple signals: next-in-series for what you're reading, new releases from monitored authors, genre similarity (≥ 20 books in library), OpenLibrary subject popular picks, and Hardcover wishlist cross-reference. Recency scoring is relative to the median publication year of your library, so backlist readers aren't penalised. Hard-filters owned, dismissed, excluded-author, wrong-language, fewer-than-50-ratings, sub-3.0-rated, and omnibus titles. Dismiss / exclude actions persist.

Migration — upload readarr.db directly (authors re-resolved against OpenLibrary since bookinfo.club is dead; indexers, download clients, and blocklist port structurally), or paste a newline-separated list of author names. CLI: bindery migrate {csv,readarr} <path> for first-time bulk imports without opening the UI.

Operations

  • Authentication — first-run setup creates an admin account (argon2id, signed session cookies). Four modes: Enabled / Local only (bypass for private IPs) / Disabled / Proxy (trust upstream X-Forwarded-User from a configured trusted proxy — drop-in for Authelia / Authentik / oauth2-proxy). Per-account API key, per-IP login rate limiting, CSRF double-submit (API-key clients exempt).
  • OIDC — native Authorization Code + PKCE with multi-provider support. Pre-configured for Google, GitHub (via Dex), Authelia, and Keycloak; identifies users by stable (issuer, sub) so email/username changes don't break logins.
  • Multi-user mode — per-user libraries, monitored authors, profiles, and downloads. Admin role manages indexers / download clients / users; standard users see only their own catalogue. Local, OIDC-provisioned, or forward-auth-mapped.
  • Webhook notifications for grab / import / failure (pipe to Apprise, ntfy, Home Assistant, Discord, Slack via proxies). Tags scope indexers / profiles / notifications to specific authors. On-demand SQLite backups. Persistent log viewer in Settings → Logs with runtime DEBUG toggle.
  • Arr-compatible queue at GET /api/queue for Harpoon and other *arr-aware tools — pagination, sort, live size, status, client, remote ID, protocol.

UI

  • Modern React 19 + TypeScript + Tailwind CSS SPA with deep-linkable routed /book/:id and /author/:id pages.
  • Light / dark themes (respecting prefers-color-scheme first paint), grid / table view toggles, mobile-friendly responsive layout, hamburger nav, agenda-style mobile Calendar.
  • Full pagination, search, filter, and sort on every list page; preferences persist to localStorage.
  • 7 languages — English, French, German, Dutch, Spanish, Filipino (Tagalog), Indonesian — auto-detected from the browser, override in Settings.
  • OPDS 1.2 catalogue at /opds/v1.2/ for KOReader, Moon+ Reader, and other reading apps. HTTP Basic auth with the API key as the password.

Packaging — single Go binary with the React frontend embedded via go:embed. Distroless container (non-root, read-only rootfs, all caps dropped, RuntimeDefault seccomp). Helm chart for ArgoCD / Flux. Pure-Go SQLite via modernc.org/sqlite — no CGO, no external database.

Quick Start

Docker

docker run -d \
  --name bindery \
  -p 8787:8787 \
  -v /path/to/config:/config \
  -v /path/to/books:/books \
  -v /path/to/downloads:/downloads \
  ghcr.io/vavallee/bindery:latest

Open http://localhost:8787, follow the first-run setup to create the admin account, and you're in.

Docker Compose

services:
  bindery:
    image: ghcr.io/vavallee/bindery:latest
    container_name: bindery
    ports:
      - 8787:8787
    volumes:
      - ./config:/config
      - /media/books:/books
      - /media/downloads:/downloads
    environment:
      - BINDERY_LOG_LEVEL=info
    restart: unless-stopped

Other install methods

Pre-built binaries for Linux / macOS / Windows (amd64, arm64, armv7, armv6), Kubernetes (Helm chart at charts/bindery/), and the Unraid Community Applications template are all covered in docs/DEPLOYMENT.md — including UID/GID setup, path remapping for multi-container deployments, the full environment-variable reference, and per-version upgrade notes.

Configuration

Bindery is configured through the web UI under Settings — indexers, download clients, quality profiles, naming, notifications, auth, and everything else runtime-tunable lives there. A small set of bootstrap-only knobs are environment variables:

Variable Default Purpose
BINDERY_PORT 8787 HTTP server port
BINDERY_DB_PATH platform-default SQLite database path
BINDERY_DATA_DIR platform-default Config directory (backups, image cache, secrets)
BINDERY_LIBRARY_DIR /books Imported ebook destination
BINDERY_AUDIOBOOK_DIR inherits library Imported audiobook destination
BINDERY_DOWNLOAD_DIR /downloads Where the download client deposits completed jobs
BINDERY_URL_BASE (empty) Reverse-proxy subpath (e.g. /bindery)
BINDERY_PUID / PGID (unset) Sanity-check assertions for the container UID/GID

The full reference (path remapping, API-key seeding, OIDC, telemetry, rate-limit knobs, cookie-Secure policy) is in docs/DEPLOYMENT.md#environment-variables.

Supported integrations

Category Implementations
Usenet clients SABnzbd, NZBGet
Torrent clients qBittorrent, Transmission, Deluge
Indexers Newznab (NZBGeek, NZBFinder, NZBPlanet, DrunkenSlug, …), Torznab (Prowlarr, Jackett, direct endpoints), with per-indexer category overrides
Notifications Generic webhooks — pipe to Apprise / ntfy / Home Assistant / Slack / Discord
Authentication Local (argon2id), API key, OIDC (Google, GitHub via Dex, Authelia, Keycloak, …), forward-auth proxy
Reading apps OPDS 1.2 catalogue at /opds/v1.2/ (KOReader, Moon+ Reader, Aldiko, …)

All download clients support Use SSL and URL Base for connections through a reverse-proxy subpath.

Architecture

Bindery is a single Go binary (chi router, distroless container) with the React 19 + TypeScript frontend embedded via go:embed, talking to SQLite in WAL mode through the pure-Go modernc.org/sqlite driver — no CGO, no external database, no sidecars.

   Newznab / Torznab
      indexers
         │
         ▼
┌────────────────────────────┐
│         Bindery            │──► SABnzbd / NZBGet / qBittorrent / Transmission / Deluge
│  Go backend + React SPA    │──► /books/ library
│  SQLite (WAL mode)         │──► Webhook notifications
└────────────────────────────┘
    ▲                    ▲
    │                    │
OpenLibrary      Google Books, Hardcover.app, DNB, Audnex, Audible
 (primary)                 (enrichers)

Component breakdown, package layout, concurrency model, and design rationale are in docs/ARCHITECTURE.md.

API

Every feature is exposed under /api/v1/*, with an arr-compatible /api/queue for external tools and an OPDS catalogue at /opds/v1.2/. Quick taste:

# Add an author by OpenLibrary ID and start monitoring
curl -X POST -H "X-Api-Key: $KEY" -H "Content-Type: application/json" \
  -d '{"foreignAuthorId":"OL23919A","monitored":true,"searchOnAdd":true}' \
  http://bindery:8787/api/v1/author

# List wanted books
curl -H "X-Api-Key: $KEY" "http://bindery:8787/api/v1/book?status=wanted"

The full endpoint catalogue, authentication rules (API key, session cookie, local-only, OIDC, proxy), CSRF semantics, and integration examples are in docs/API.md.

Documentation

Topic Where
Quickstart — first author to first grab in 10 minutes Wiki
Deployment — Docker, Compose, k8s/Helm, binary, UID/GID, env vars, upgrades docs/DEPLOYMENT.md
Architecture — components, data flow, dependencies docs/ARCHITECTURE.md
API — REST endpoints, auth, integration patterns docs/API.md
ABS import — setup, path remap, review queue, rollback, matching behavior docs/abs_import.md
Enhanced Hardcover series — token setup, series linking, catalog diffs, missing-book fill docs/Hardcover-Series-Wiki.md
Roadmap — planned work and explicitly-out-of-scope items docs/ROADMAP.md
Contributing & CI checks — dev setup, full quality/security matrix, local check suite CONTRIBUTING.md
Changelog — release notes CHANGELOG.md
Reverse-proxy & SSO setups — Traefik / Caddy / Nginx / Authelia / Authentik recipes Wiki
Troubleshooting — permission-denied, path-remap, import failures Wiki
Indexer & download-client recipes — NZBGeek / DrunkenSlug / Prowlarr / Jackett / SAB / qBit tips Wiki
Migrating from Readarr — step-by-step with known failure modes Wiki

Community

  • Discord — real-time help, setup questions, release chat: discord.gg/RpuYYRM9cZ. The #support channel is the best place to ask; #changelog is updated on every release.
  • GitHub Issues — bug reports and feature requests: issues.
  • GitHub Discussions — open-ended design questions, show-and-tell, integration recipes: discussions.

Please keep security reports out of Discord and public issues — see SECURITY.md for the private disclosure channel.

Security

Security scans OpenSSF Scorecard Dependabot Security policy

Bindery holds API keys, reaches LAN services, and writes to disk — we take that seriously. Every push and weekly cron runs gosec, govulncheck, Semgrep, gitleaks, Trivy, Grype, Dockle, Syft, ZAP baseline, and OpenSSF Scorecard, with findings published as SARIF in GitHub's Security tab. Release images ship with SLSA build provenance and Syft SBOMs. In-app: SSRF guards on every outbound URL, hardened response headers (CSP, frame-deny, referrer-policy, auto-HSTS), distroless non-root read-only rootfs container with all caps dropped, and digest-pinned base images.

To report a vulnerability, follow the process in SECURITY.md. The full threat model and verification recipes live on the wiki Security page.

Telemetry

Bindery sends one anonymous ping per day to api.getbindery.dev so the maintainer can count active installs. The payload contains a random install_id (generated on first run), the binary version, os, and arch — no hostnames, IP addresses, library contents, or personal data. The response carries the latest published version, used for in-app update notifications. Opt out with telemetry.enabled: false in Settings → General, or BINDERY_TELEMETRY_DISABLED=true before first run.

Contributing

PRs, issues, and feedback welcome. See CONTRIBUTING.md for the dev setup, the full local check suite, and the PR flow. Tracked feature work lives in docs/ROADMAP.md — open an issue before starting anything substantial.

License

MIT. See LICENSE for details.

Acknowledgments

  • The *arr community for pioneering the monitor-search-download-import pattern
  • OpenLibrary for free, open book metadata
  • The Readarr project for the original vision, even though the implementation couldn't be sustained

About

Automated book download manager for Usenet. Monitor authors, search indexers, download via SABnzbd, and organize your library. The modern replacement for Readarr.

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors