---
title: "@insurgently/library-hub-api"
built: 2026-10-30
source: api/README.md
html: https://insurgently.com/projects/library-hub/technical/agents/README
---
# @insurgently/library-hub-api

> Index of these files: https://insurgently.com/projects/library-hub/technical/agents/llms.txt

Types and a few small helpers for reading books from [Library Hub](https://github.com/insurgently/library-hub) in your own Obsidian plugin.

Library Hub keeps a book collection in a vault: Calibre and other providers, book notes, shelves, a reader. Its API lets another plugin list books and shelves, get a book's file or its text, open the reader at a passage, and change shelves with undo. This package is that API's contract: the types, the version it describes, and the code that finds the plugin.

It has no dependencies and imports nothing at runtime. Your bundler keeps what you use.

## Install

```sh
npm install --save-dev @insurgently/library-hub-api
```

Use a tilde, so you take patch fixes only, and raise the minor when you're ready for what it adds.

## Quick look

```ts
import { getLibraryHub, onLibraryHubReady, hasMethod, type LibraryHubApi } from '@insurgently/library-hub-api';

const WANTED = '0.8.0';

export default class MyPlugin extends Plugin {
	libraryHub: LibraryHubApi | null = null;

	onload() {
		// now if Library Hub is loaded, and again each time it loads (the user can turn it off and on)
		onLibraryHubReady(this.app, this, WANTED, (api) => (this.libraryHub = api));
	}

	async chapters(book: string) {
		const found = getLibraryHub(this.app, WANTED, { by: 'My Plugin', for: 'for its reading lists' });
		if (!found.libraryHub) return new Notice(found.message);
		const text = await found.libraryHub.bookText(book); // a Calibre id, a note, a file, an ISBN…
		return text.chapters.map((c) => `${c.n}. ${c.title} (${c.location})`);
	}
}
```

A chapter's `location` is what `openBook` takes, so you can send the reader back to it later:

```ts
await libraryHub.openBook(book, { location: chapter.location, quote: 'a sentence from the passage' });
```

## How it behaves

- **Versions.** `getLibraryHub(app, wanted)` checks the installed API against the version you built for: same major, and a minor at least as new. Gate on the lowest minor you need. A method newer than your gate says `@since` in its comment: check it with `hasMethod(api, 'bookText')` first.
- **Reloads.** Library Hub fires `library-hub:ready` each time it loads. `onLibraryHubReady` listens for it through your plugin, so the listener goes when your plugin unloads.
- **Errors.** Every method rejects with an `Error` whose `code` is a `LibraryHubErrorCode` (`server-off`, `book-missing`, `needs-conversion`…) and whose message says, in plain words, what went wrong and what to do. Branch on the code. Show the message.
- **Books.** A `BookRef` names a book: a Calibre id, a note's path or name, a book file, an ISBN, a Calibre uuid, or a provider's id. Numbers work wherever they did before.
- **Text.** `bookText` gives a book's chapters with their text, a `location` for each, offsets in code points, and a hash of the whole text that changes only when the text does. `bookChapters` is the same without the text. Converting an AZW3 or MOBI adds a file to the user's Calibre library, so it only happens when you pass `{ convert: true }`, and the user is asked first.
- **Tools.** The table of Library Hub's operations as model tools is at `@insurgently/library-hub-api/tools`. Library Hub registers them itself; you only need it to map them somewhere else.
- **Old names.** `getBooks`, `onBooksReady`, `BooksApi` and the `BOOKS_*` constants, from before the plugin was renamed, still work and are deprecated. Deprecated names go at 1.0, not before.

The full reference is `dist/index.d.ts`, with a comment on every declaration.

## Versions

The package's version is the API's version. It's published after the Library Hub release that serves it, so you can't build against an API nobody has yet. [CHANGELOG.md](https://insurgently.com/projects/library-hub/technical/agents/CHANGELOG.md) says which release that is.

MIT licensed.
