⚠️ Warning! It's in really early stages of development, test it but expect bugs!
Lightweight aggregator ("Backbone") for audiobook providers.
Searches multiple providers (lubimyczytac, audioteka, storytel, ...) and returns ranked results, with optional merging of best matches and controlled detail-page fetches to minimize load on upstream sites.
You can search besides abs on
http://<host>:4000/search-ui
- Providers (audioteka, lubimyczytac, storytel at the moment) return small search snippets (title, id, url, minimal fields).
- Backbone scores each snippet by title/author similarity (configurable weight).
- Backbone applies per-provider caps and a global similarity threshold.
- Backbone fetches full metadata (detail pages) only for the small candidate set.
- Optional "merge best results" builds a single superior result from multiple top matches, with per-field provider preference rules.
You can set them on
http://<host>:4000/admin
- Global controls:
titleWeight(0–100) — weighting between title vs author similarity (sums to 100).similarityThreshold(0–100) — minimal similarity (%) to request full metadata.mergeBestResults(bool) — synthesize merged top result.mergePreferences(map) — prefer a provider for specific fields (cover, narrator, series, genres, tags, subtitle, isbn, etc.).mergeDebug(bool) — enable extra merge logs.
- Per-provider controls:
enabled,priority,languages,maxResults— limit noisy providers.- provider-specific
extrasettings (e.g.,audioteka.extra.addLinkToDescription).
- Minimal, informative logging:
- provider snippet counts, candidate counts, planned full-fetch count, merged provenance.
- Admin UI:
http://<host>:4000/admin - Search UI:
http://<host>:4000/search-ui - API:
- GET
/admin/config— read config - PUT
/admin/config— save config (body: full config JSON) - GET
/admin/providers/meta— provider metadata (supported languages, etc.) - GET
/search?query=...&author=...&lang=...— perform search, returnsmatchesarray (merged items include_provider: "merged"and_mergedFrom/_mergedFieldSources)
- GET
Example search via CLI:
curl 'http://localhost:4000/search?query=Zrost&author=Robert%20Ma%C5%82ecki' -s | jq '.matches | .[0:5]'Project includes docker-compose.yml:
version: '3.8'
services:
aioabs-backbone:
image: lakafior/aio-abs-providers:latest
container_name: aio-backbone
ports:
- "4000:4000"
environment:
- NODE_ENV=production
volumes:
- ./src/config:/src/config
- ./logs:/logs
restart: unless-stoppedRun locally:
# start container
docker compose up -d
# view logs
docker compose logs -f backbone
# stop
docker compose downPersistence:
./configis mounted into container -> keepconfig/config.jsonedits persistent../logsoptionally mounted
Backbone returns results in a normalized ABS-friendly shape. To configure it in Audiobookshelf just add it as custom provider:

- Navigate to your AudiobookShelf settings
- Navigate to Item Metadata Utils
- Navigate to Custom Metadata Providers
- Click on Add
- Name: whatever for example AudioTeka
- URL: http://your-ip:4000
- Save
- Still seeing many detail fetches? Confirm providers are updated to return snippets (searchBooks must not call getFullMetadata). If you have custom provider, follow the snippet+getFullMetadata pattern.
- Missing fields in Audiobookshelf? Check
author(string) andseriesarray-of-objects format. - Admin UI not saving? Check that
configdirectory is writable and mounted if running in Docker.
- Follow existing code style.
- When adding a provider:
- Implement
searchBooks(query, author, lang)→ return snippet objects - Implement
getFullMetadata(snippet)→ return full normalized metadata (ABS shape) - Avoid performing detail-page fetches inside
searchBooks
- Implement