# Project pack: Audiobookshelf @ 743d915

Facts about **Audiobookshelf** for an AI following the [BespokeAI handover guide](https://handoff.bespokeai.software/guide/v1.md). This pack is pinned to one version and never changes after publication.

> Audiobookshelf turns a folder of audiobooks and podcasts into a beautiful library you can listen to anywhere. It remembers where each person stopped, on every device, and fetches covers and book details for you. Everyone in the family gets their own login and progress. It runs on your own computer or server, with free phone apps.

## Version and source
- Repository: https://github.com/advplyr/audiobookshelf
- Pinned commit: `743d9152208507a1dbf7c95c94290071338f44bd`. Use exactly this version.
- Get it: `git clone https://github.com/advplyr/audiobookshelf audiobookshelf && cd audiobookshelf && git checkout 743d9152208507a1dbf7c95c94290071338f44bd`
- Or download a zip: https://github.com/advplyr/audiobookshelf/archive/743d9152208507a1dbf7c95c94290071338f44bd.zip
- Official docs: https://www.audiobookshelf.org/docs
- Live demo: https://audiobooks.dev (username: demo / password: demo). Community-hosted web demo with an ordinary user account. Shared with everyone.
- Licence: **GPL-3.0-only**. Free to use and change. If you share your changed version with other people (give them the code or app), you must share your source code under the same licence. Running it for yourself and your household has no extra obligations.

## Running it
- Easiest: Save the docker-compose.yml from this repo, put your audiobooks in ./audiobooks and podcasts in ./podcasts, then run: docker compose up -d # then open http://localhost:13378 and create the root (admin) user
- Needs: Docker, or for development Node.js 24 + FFmpeg
- Develop: `npm ci && (cd client && npm ci && npm run generate) && npm run dev   # needs a dev.js (example in .devcontainer/dev.js); server and client on :3333`
- Test: `npm test`
- Check/lint: `npm run lint`
- Stack: javascript, vue, css (Node.js 24, Express, Sequelize, Nuxt 2, Vue 2, Tailwind CSS 4). Difficulty for a non-developer with an AI: **moderate**. A Node.js server with a Nuxt 2 web client and a single SQLite database. Most family needs are settings. Upstream is rewriting the web client in React and is not taking pull requests for the current Vue client, so client changes stay in your own copy.

## Customisation points (settings → extend → code)
- **libraries-and-folders** [settings]: Which folders hold books or podcasts, and how titles, authors and series are read from folder names and tags. → `Settings → Libraries (client/pages/config/libraries.vue); folder naming rules in the library docs`
- **users-and-permissions** [settings]: A login per family member, with what each can see (e.g. hide adult books from children) and whether they can download. → `Settings → Users (client/pages/config/users/)`
- **metadata-sources** [settings]: Where covers and book details come from, plus your own genres and tags. → `Library settings and Settings → Item metadata utils (providers in server/providers/)`
- **notifications** [extend]: Messages when new podcast episodes download or a backup fails. → `Settings → Notifications with an Apprise API URL (events in server/utils/notifications.js)`
- **custom-metadata-provider** [extend]: Plug in your own book-details service, e.g. for a language or publisher the built-in sources miss. → `Settings → Item metadata utils → Custom metadata providers; contract in custom-metadata-provider-specification.yaml`
- **api-and-rss** [extend]: Scripts, smart-speaker skills and other players that read your library or progress. → `REST API (docs/openapi.json), API keys in Settings → API Keys, RSS feeds per book or podcast`
- **web-client** [code]: New screens, layouts and colours in the current Vue web client. → `client/pages/**, client/components/**, client/assets/tailwind.css, client/strings/en-us.json`
- **server** [code]: New data, new API endpoints and background jobs. → `server/controllers/**, server/routers/ApiRouter.js, server/models/**, server/managers/**, server/migrations/`

## Must keep working
- Your media files. Audiobookshelf must never move, rename or delete them unless you ask.
- Listening progress and bookmarks for every user, across the web client and the phone apps.
- The REST API and socket events, because the Android and iOS apps depend on them.
- Database changes need a new migration in server/migrations/ named <version>-<name>.js; never edit old ones.
- User permissions (a child's account must not see restricted libraries or tags).

## Staying updatable
Settings, notifications, custom metadata providers and the API cover most needs without a fork. Upstream is replacing the Vue web client with a React one and won't merge changes to the current client, so keep client changes small and in new files.

## Data, costs and safety
- Personal data: **yes**. Stored in: SQLite database in /config; covers, cache and backups in /metadata; your audio files stay in your own media folders. Listening progress and user accounts are in /config. Settings → Backups can make scheduled backups of the database and metadata; check that the schedule is switched on. Back up your media folders separately; Audiobookshelf does not copy them.
- Service: Book and podcast metadata (Audible, Google Books, Open Library, iTunes, Audnexus and others) (optional, free): Covers, descriptions, series and chapter lists. Only used when you search for or match a book.
- Service: Apprise API server (optional, free (self-hosted)): Notifications such as "new podcast episode downloaded" or "backup failed" to Telegram, Discord, email and more.
- Service: Email (SMTP) (optional, free with most providers): Send ebooks to an e-reader such as a Kindle.
- Setting `PORT`: The port inside the container or on the server (80 in Docker; change only the outside port).
- Setting `CONFIG_PATH`: Where the database and settings live (/config in Docker).
- Setting `METADATA_PATH`: Where covers, cache and backups live (/metadata in Docker).
- Self-hosted with its own login. Use strong passwords and HTTPS (with websocket support) before exposing it to the internet.
- Give children and guests ordinary user accounts, not admin.
- API keys and SMTP passwords are secrets. Never paste them into an AI chat.

---

# Customising Audiobookshelf

Audiobookshelf is a Node.js server with a Nuxt 2 (Vue) web client. **Most family adaptations are settings.** Upstream is rewriting the web client in React and is not reviewing pull requests for the current Vue client, so any client change lives only in your own copy.

## Level 1: Settings (no code)
- **Libraries:** Settings → Libraries. Point a library at your audiobook or podcast folders. Folder names matter: follow the library docs (Author / Series / Title) so books are recognised correctly.
- **Users and permissions:** Settings → Users. One login per person, each with their own progress. Limit which libraries and tags a user can see, and whether they can download, update or delete.
- **Book details:** choose metadata sources per library, and manage your own genres and tags under Settings → Item Metadata Utils.
- **Podcasts:** add a podcast by search or RSS and turn on auto-download for new episodes.
- **Backups:** Settings → Backups. Set a schedule and how many backups to keep.
- **E-readers:** Settings → Email. Add SMTP details and e-reader devices to send ebooks to a Kindle.

## Level 2: Extend (no fork)
- **Notifications:** Settings → Notifications. Point it at an Apprise API server, then pick events such as "podcast episode downloaded" or "backup failed". Apprise forwards them to Telegram, Discord, email, ntfy and more.
- **Custom metadata provider:** a small web service you write that follows `custom-metadata-provider-specification.yaml`, added under Settings → Item Metadata Utils → Custom Metadata Providers. Good for books the built-in sources don't know.
- **REST API:** described in `docs/openapi.json`. Create a key under Settings → API Keys. Use it for scripts, stats or a smart-speaker skill.
- **RSS feeds:** open a feed for a book or podcast to listen in any podcast app.

## Level 3: Code
There is no upstream `AGENTS.md`. Follow the readme's "Run from source" section.

| Change | Where |
|---|---|
| New page | `client/pages/**` (Nuxt 2 file-based routes) |
| Components and player | `client/components/**` (player in `client/components/player/`, app shell in `client/components/app/`) |
| Colours and styles | `client/assets/tailwind.css`, `client/assets/app.css` |
| Text | `client/strings/en-us.json` (other languages come from Weblate) |
| API endpoint | `server/routers/ApiRouter.js` → `server/controllers/*Controller.js` |
| Background jobs | `server/managers/**` |
| New data | `server/models/**` plus a migration in `server/migrations/` named `<next version>-<name>.js` (see `server/migrations/readme.md`) |

## Running locally
- **Just use it:** save `docker-compose.yml` from the repo, put books in `./audiobooks` and podcasts in `./podcasts`, run `docker compose up -d` and open http://localhost:13378. The first screen asks you to create the root (admin) user.
- **Develop:**
  1. Install Node.js 24 and FFmpeg (or use the dev container in `.devcontainer/`).
  2. Copy `.devcontainer/dev.js` to `dev.js` in the repo root and adjust the paths.
  3. Run `npm ci`, then `cd client && npm ci && npm run generate && cd ..`.
  4. Run `npm run dev` and open http://localhost:3333.
  5. For live client reload, also run `cd client && npm run dev` (port 3000).
- **Check:** `npm test` (server tests) and `npm run lint`.

## Pitfalls
- Never let changes touch the media folders themselves. They are the family's collection, and Audiobookshelf does not back them up.
- The phone apps use the same API and socket events. Changing an existing response can break them; add new fields instead.
- After client changes in the normal dev setup, run `npm run generate` in `client/` again and restart the server.
- Reverse proxies must pass websockets, or progress sync and live updates stop working.
- Keep client changes small. Upstream will replace the Vue client, so large changes will need redoing later.

---
Machine-readable: [bespoke.yaml](https://handoff.bespokeai.software/p/audiobookshelf/743d915/bespoke.yaml) · Agent skill: [SKILL.md](https://handoff.bespokeai.software/p/audiobookshelf/743d915/SKILL.md)
