Automated book download manager for Usenet & Torrents
Monitor authors. Search indexers. Download. Organize. Done.
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.
Library management
- Author monitoring via OpenLibrary's author-works endpoint, with per-book monitor toggles and a
wanted → downloading → downloaded → importedworkflow. - 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/.mp3folders 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 Haywoodmerge 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=book→surname+title→author+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
wantedflip, 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:
calibredbCLI hook on import, Bindery Bridge plugin (cross-container), or direct read of an existing Calibre library'smetadata.dbas 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-Userfrom 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/queuefor 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/:idand/author/:idpages. - Light / dark themes (respecting
prefers-color-schemefirst 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.
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:latestOpen http://localhost:8787, follow the first-run setup to create the admin account, and you're in.
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-stoppedPre-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.
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.
| 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.
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.
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.
| 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 |
- Discord — real-time help, setup questions, release chat: discord.gg/RpuYYRM9cZ. The
#supportchannel is the best place to ask;#changelogis 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.
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.
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.
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.
MIT. See LICENSE for details.
- 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



