Tracked feature requests for future releases. Not a commitment — priorities shift based on user feedback and available time. Open an issue to propose additions.
The short version lives in the README. ✅ items have landed (either in a tagged release or on development); ⬜ items are planned. Items with sub-lists track partially-shipped work.
-
✅ Multi-user support (v1.0.0/v1.0.1) — per-user libraries, per-user monitored authors, per-user quality profiles.
Today Bindery assumes a single administrator — the auth schema has a
userstable but is seeded with exactly one row. Multi-user support needs role/permission scoping across the rest of the schema and UI:- Author / book / profile rows gain an
owner_user_idor join-table membership. - Handlers filter by the authenticated session's user.
- The settings page splits into per-user (API key, password, preferences) and admin-only (indexers, download clients, system).
- Migration from single-user → multi-user re-parents all existing rows to the admin account.
- Author / book / profile rows gain an
-
OIDC / SSO — support both deployment shapes so Bindery fits any environment.
- ✅ Native OIDC client (v1.0.0) — sign in directly against Authelia / Authentik / Keycloak / Google / GitHub without a reverse proxy in the path. Session cookies from the OIDC flow live alongside the existing username/password and API-key auth; users can mix.
- ✅ Reverse-proxy SSO (v1.0.0) — accept upstream-proxy identity headers (
X-Forwarded-User/Remote-User) when the request arrives from a configured trusted proxy IP. First-classproxyauth mode with startup guard. See the Reverse-proxy & SSO wiki page.
Goal: the same release supports both homelab users who already run Authelia at the edge and users who want to plug OIDC straight into Bindery without standing up a proxy.
-
✅ Reverse-proxy header trust (v1.0.0) —
X-Forwarded-User(configurable) trusted fromBINDERY_TRUSTED_PROXYCIDR list. Startup refuses to start in proxy mode without a trust list configured. -
✅ CSRF tokens (v1.0.0) — double-submit token via
GET /auth/csrf; all session-cookie mutations require matchingX-CSRF-Tokenheader. API-key clients exempt. See Use CSRF tokens in scripts. -
External database support (MySQL / Postgres) (#86)— Won't do. SQLite with WAL mode handles all realistic single-instance and multi-user load. Introducing an external database server adds operational burden (credentials, backups, version management, connection pooling) with no concrete benefit for the homelab use case. Closed. -
UI localization (i18n) — translate the web UI into French, Dutch, and German (starting point; more languages welcome as contributors show up).
- ✅ Translation-catalogue extraction pass (landed in v0.12.0).
- ✅ Runtime switcher (language selector in Settings, persisted in
localStorageso it applies before first paint alongside the theme). - ✅ Locale-aware date/number formatting.
- ✅
Accept-Languageauto-detect on first load with manual override.
-
✅ Direct title/keyword search (#85, #267, landed in development) — Search page at
/searchlets users search all enabled indexers by title, author, or keyword directly from the nav without adding an author first. Results display inline with a Grab button. Backend endpoint (GET /api/v1/indexer/search) already existed; PR #266 added the dedicated UI. -
Cover image privacy / local caching — prevent the browser from contacting third-party image hosts (Goodreads, OpenLibrary, Google Books) directly, which would leak the user's IP and reading habits.
- ✅ Server-side image proxy cache (closes #112, landed in development) —
GET /api/v1/images?url=<encoded>fetches and caches cover images under<dataDir>/image-cache/with a 30-day TTL. AllimageURLfields in API responses are rewritten to this proxy path before leaving the server. No browser-to-third-party requests, no fingerprinting.
- ✅ Server-side image proxy cache (closes #112, landed in development) —
-
Non-English indexer / metadata support — let monitored authors and searches pull from language-tagged catalogues and filter results by language.
- ✅ Per-author metadata profiles carry an
allowed_languageslist; OpenLibrary works whose language falls outside it are dropped during author ingestion (#14, landed in v0.6.0). - ✅ Propagate the profile's languages into indexer queries (Prowlarr's
Categories+ language filters, Jackett/api?cat=7000&...) so Newznab-side filtering applies (landed in v0.12.0). - ✅ Surface the language tag in search-result and wanted-books views.
- ✅ Persist Hardcover/Google Books'
languagefield for editions. - ✅ DNB (Deutsche Nationalbibliothek) metadata provider (#67, landed in development) — public SRU endpoint (
services.dnb.de/sru/dnb) with MARC21-XML record schema; no API key. Always-on enricher alongside Hardcover. Fills description, language, year, publisher from MARC fields. Especially useful for German-language titles where OpenLibrary / Google Books coverage is thin.
- ✅ Per-author metadata profiles carry an
-
LinuxServer.io-style runtime user switching (#56)— Won't do. The distroless image is deliberately minimal (no shell, nogosu). Runtime UID/GID switching requires a shell entrypoint, which contradicts the minimal-attack-surface posture. Pass--user <uid>:<gid>todocker runor setsecurityContext.runAsUserin Helm. Closed as won't-fix. -
Import mode — move / copy / hardlink (#54)
- ✅ Move / Copy / Hardlink (landed in v0.12.0) — configurable under Settings → General → Import Mode. Hardlink requires the download dir and library on the same filesystem. Copy preserves the source so torrent clients continue seeding.
-
Calibre library integration — treat a Calibre library as a first-class storage target, for users who already live in Calibre or want e-reader sync.
The user-facing goal: a monitored author releases a new book, Bindery finds and grabs it, and the result lands in Calibre under the existing author automatically — no manual "Add books" step.
- ✅ Path A —
calibredbpost-import hook (#32, landed in v0.8.0) — every successful Bindery import is mirrored into the configured Calibre library by shelling out tocalibredb add --with-library <path>. The returned Calibre book id is persisted on the Bindery book row so future OPDS / sync work has a stable handle. Opt-in via Settings → General → Calibre (enabled / library path / binary path) with a Test connection button. - ✅ Library import & sync (#63, landed in v0.9.0) — reads an existing Calibre library's
metadata.dbdirectly (pure Go, no CGO, read-only) and ingests it as Bindery's catalogue. Three-tier dedup (by Calibre id → title+author → insert new) makes re-imports idempotent. Co-authors become alias rows. Trigger via Settings → General → Calibre → Import library orcalibre.sync_on_startup. Path B — Calibre-watched drop folder (#64, landed in v0.9.0, removed in v0.17.0)— The drop-folder mode copied files into a Calibre-watched directory and polledmetadata.dbfor the resulting book id. This mode has been removed because it fundamentally depends on the Calibre GUI application running and its auto-add watcher being active. In a containerised / headless deployment (the primary Bindery use case), the Calibre GUI is not reliably open, so the watcher never fires and books silently time out. Thecalibredbmode achieves the same result without any of these constraints — it requires only that both Bindery and Calibre share the library directory via a volume mount, which is already required for the library import/sync feature.- ✅ Configurable per-library mode (#64, landed in v0.9.0) — Settings → General → Calibre exposes a mode selector: Off or calibredb CLI. Toggling takes effect without a restart.
- ✅ OPDS feed (#65, landed in v0.9.0) — OPDS 1.2 Atom catalogue at
/opds/v1.2/so KOReader / Moon+ Reader / etc. can browse and download without running Calibre itself. Authenticated with HTTP Basic Auth (API key as password).
- ✅ Path A —
-
✅ Default library location configurable from Settings UI (#332) — a new "Default root folder" dropdown in Settings → General lets users pick any configured root folder as the library fallback for authors with no per-author root folder.
BINDERY_LIBRARY_DIRcontinues to work as an env-var fallback when the setting is unset. -
✅ Split ebook / audiobook results in search (#333) — when both ebook and audiobook indexers are enabled, the search results page shows only one media type at a time based on the active filter. A two-section layout (ebooks / audiobooks) would surface both in the same view so users can compare and grab from either without toggling.
-
✅ Calibre-Web-Automated (CWA) ingest (#417) — when the operator runs CWA in a sibling container, bindery copies every successful ebook import into a configured shared ingest folder so CWA's auto-ingest picks it up automatically. Bindery keeps its own copy. No Calibre runtime dependency in the bindery container. Configured under Settings → General → Calibre-Web-Automated (CWA).
-
Editable quality profiles — today the Settings → Quality tab is read-only: the seeded profiles render but there's no way to create, rename, delete, or toggle which formats are allowed. The filtering logic itself already works (
internal/decision/specs.goQualityAllowed), so a user-edited profile that only ticksepubwould correctly rejectpdf/azw3/mobireleases — the editor surface is what's missing. Scope: a profile form in the existing Quality tab plus POST/PUT/DELETE handlers under/api/v1/qualityprofile.
These items are too large or architectural for a minor release. They define the v2 milestone — the set of changes that would warrant a major version bump.
-
✅ Multi-user with role separation — shipped in v1.0.0/v1.0.1.
-
✅ Native OIDC / SSO with multi-provider discovery — shipped in v1.0.0.
-
External database (MySQL / Postgres) (#86)— Won't do. Closed as won't-fix; see the Planned section above. -
✅ Persistent structured log store (#241, landed in development) — Persists log entries to SQLite (migration 026), survives restarts, queryable by date range / level / component / full-text. Retention defaults to 14 days and is configurable. The ring buffer remains as a fast in-process fallback when no DB is available.
-
Soulseek as a download source (#417) — Soulseek's slsk:// P2P protocol is stateful and session-oriented (handshake, peer discovery, queue, transfer, slot management) — fundamentally different shape from the fire-and-forget HTTP fetch of NZB/torrent/magnet that bindery's queue assumes today. Adding it requires a long-lived peer connection in the bindery process, a search-result schema rich enough to carry slsk peer/file/size metadata through the ranker and quality-profile machinery, and either a vendored slsk client (e.g. slingamn/slsk) or a sidecar daemon with its own configuration story. Worth doing because of the genuinely strong content catalogue on the network, but not before the v2 milestone.
These get asked often enough to warrant a standing answer. They're not on the roadmap and new issues requesting them will be closed with a link here.
Bindery's search pipeline is built on documented, stable public APIs — Newznab, Torznab, OpenLibrary, Google Books, Hardcover. Shadow libraries don't fit that posture:
- Legal risk — hosting integration code against a service under active copyright litigation exposes the project and anyone running it. The *arr ecosystem's deliberate distance from these sources is the same call.
- API instability — shadow-library endpoints move, rename, get seized, and return in different forms. The "documented, stable" test exists specifically to keep Readarr's
api.bookinfo.clubfailure mode from recurring. - Search quality — these services don't publish structured metadata (no foreign-book-id mapping back to OpenLibrary works), so results can't be ranked against the quality-profile / edition / language machinery that drives the rest of Bindery.
If you need these sources, point a Jackett / Prowlarr instance at them and wire that into Bindery via Torznab. The indexer layer is a proxy boundary by design — what lives behind it is the operator's choice.
OpenBooks (IRC-based ebook retrieval from #ebooks on IRCHighway) is a great tool but doesn't compose with Bindery's architecture:
- Protocol mismatch — IRC DCC transfers are stateful, session-oriented, and manual (
@search→ results →!<bot> <filename>). Bindery's fire-and-forget grab → queue → import pipeline assumes an HTTP-fetchable URL (NZB,.torrent, magnet). - No result metadata — IRC search results are filenames, not structured release objects with size / pub-date / grabs / indexer ID. The ranker and custom-format matchers would degenerate to substring matching.
- Maintenance burden — IRC bots rotate, channel rules change, trigger syntax drifts. Absorbing that churn into the release pipeline isn't in scope for a single-maintainer project.
Run OpenBooks alongside Bindery for one-off lookups — it's a different tool with a different shape, and pretending otherwise degrades both.