Skip to content

PDF Library

A reading list with an in-app PDF reader and annotations

Overview

PDF Library is a reading list with a built-in PDF reader. You collect PDFs — by pasting a URL or uploading a file — track which ones you have read, and open any of them in a smooth, continuous reader where you can search the text and mark it up with colored highlights and notes. It is part of the kimtos new-tab app suite.

Everything is fully on-device. There is no backend, no account, and no network round-trips while you read: every book, the PDF file itself, your reading progress, and your annotations live in your browser's IndexedDB and never leave the machine.

Highlights

  • Build a reading list — import a PDF by URL or upload one from your computer. The file is downloaded/stored locally, so it opens instantly later.
  • Track progress — a read checkbox per book, plus All / Unread / Read filters. Unread books sort first; read ones fall below a divider.
  • Dock badge — the app's dock icon shows how many books are still unread.
  • Continue reading — a home-screen widget lists the books you read most recently, so you can jump straight back in.
  • Continuous reader — every page stacked in one scroll, rendered on demand, with manual zoom and a live page indicator.
  • Remembers where you were — your last page and zoom level are saved per book and restored when you reopen it.
  • Search the whole book — find a word or phrase across every page, with matches fully highlighted even when they break across the PDF's text chunks.
  • Highlights, notes & annotations — select text to highlight it in one of four colors, attach a comment, and browse everything in a notes sidebar.

Privacy model

PDF Library writes only to local browser storage:

  • Books (title, source, read state, last page, zoom) are records in IndexedDB.
  • The PDF files themselves are stored as binary blobs, one per book.
  • Annotations (highlights and comments) are separate records linked to a book.

When you import by URL, the PDF is fetched once and saved locally; from then on it is read from your own storage and rendered in the browser. Nothing is uploaded, and there are no analytics or third-party calls.

Getting Started

Open PDF Library from the dock. You land on your reading list — empty at first, with a form at the top for adding your first book.

Adding books

There are two ways to add a PDF, both from the top of the list:

  • Import by URL — paste a link to a PDF into the "Paste a PDF URL to import" field and click Import. The file is downloaded and stored locally.
  • Upload a file — click Upload a PDF from your computer and pick a file.

A Title field above both is optional. If you leave it blank, the title is taken from the file name (or the last part of the URL). Either way, as soon as the book is added it opens straight into the reader. Files are capped at 50 MB, and non-PDF files are rejected.

Managing the list

  • Filters — the All / Unread / Read tabs narrow the list. In All, unread books come first and a "Read" divider marks where the read ones begin.
  • Mark read / unread — tick the checkbox on a book's row. The dock badge (the unread count) updates accordingly.
  • Open — click a book to open it in the reader. Each row shows its source (the host for URL imports, or "Uploaded PDF") and, if you have read past the first page, the page you left off on.
  • Remove one — the trash button on a row deletes that book (with a confirm).
  • Remove several — tap Select (or drag across rows), tick the books, and delete them in one batch.

Reading

The reader is a continuous, scrolling view: all pages are stacked top to bottom, and each one renders as it nears the screen. The toolbar gives you everything else.

  • Scroll & page indicator — just scroll to move through the book. A live page / total counter in the toolbar tracks where you are.
  • Zoom — use the and + buttons; the current percentage shows between them. Pages open at their natural size (shrunk to fit only if wider than the view) and your zoom level is remembered per book.
  • Remember last page — the reader reopens at the page (and zoom) you left off on.
  • Back — the back arrow (top-left) returns to the reading list.

Searching

Type into the Search in book… field and press Enter. Every match across the whole book is highlighted, and the reader jumps to the first one. A counter shows match / total; the and buttons step between matches (pressing Enter again advances to the next). Search ignores whitespace, so a phrase is found even when the PDF splits it across separate text chunks.

Highlights, notes & annotations

  • Create a highlight — select some text in a page. A small popup appears with four colors (yellow, green, blue, pink); click one to highlight the selection.
  • Add a note — in that same popup, click Note to highlight and immediately open a comment box. Type your note and click Save.
  • Edit later — click an existing highlight to reopen the popup, where you can change its color, edit its comment, or delete it.
  • Annotations sidebar — the Notes button (toolbar) opens a side panel listing every highlight and comment in order, with a color dot and page number. Click an entry to scroll to it (it flashes briefly); use the trash icon to delete it.

Architecture

PDF Library follows the suite convention: all data logic lives behind the local API layer, and the app itself is UI plus a self-contained PDF.js reader. The code lives in extension/src/apps/pdflib/.

Modules

FileRole
index.tsThe app descriptor and list UI — add-by-URL / upload form, the All / Unread / Read filters, the read checkbox and remove/batch-delete, the dock unread badge, and the "Continue reading" home widget.
reader.tsThe in-app reader — a PDF.js continuous viewer with on-demand page rendering, manual zoom, a live page indicator, last-page memory, cross-chunk text search & highlight, and the highlights / comments / annotations sidebar. Loaded lazily, so PDF.js stays out of the main bundle.
pdflib.local.tsThe data layer — book CRUD, stored PDF blobs, and annotation CRUD over IndexedDB, registered on the local API router.

Data flow

The UI never touches storage directly: both the list and the reader call getApi / jsonApi (the suite's local router), which dispatches to pdflib.local.ts. To display a book, the reader asks the data layer for a blob URL of the stored PDF, hands it to PDF.js, and renders each page to a <canvas> as it scrolls into view.

The reader

The reader stacks one wrapper per page and renders lazily:

  • An IntersectionObserver renders pages as they approach the viewport (with a buffer) and unloads pages that scroll far away, to bound memory.
  • Pages render at the chosen zoom only; the page wrappers are pre-sized so the scrollbar and page indicator stay correct before a page has drawn.
  • A text layer over each canvas powers selection, search highlights, and a separate highlight layer whose rectangles are positioned in percentages of the page box — so annotations track zoom for free.
  • Search builds a whitespace-stripped string of each page's text (cached) to find matches across chunk boundaries, then wraps exactly the matched characters in <mark> elements.

Persistence

Three kinds of record back the app:

book        { id, title, url, source, read, added, lastPage, lastReadAt, zoom }
PDF blob    key "pdf:<bookId>"  →  the stored PDF file
annotation  { id, bookId, page, rects[], text, color, comment, created }

Reading progress (lastPage, lastReadAt) and zoom are saved with a short debounce as you read. Highlight geometry is stored as normalized rects (fractions of the page), so it renders correctly at any zoom. Deleting a book removes its record, its stored PDF blob, and all of its annotations.

Reference

A quick reference for the reader controls, data, and limits.

Reader controls

ControlWhat it does
Back (‹)Return to the reading list.
Search fieldFind a word or phrase across the whole book; press Enter to run / advance.
Match counterShows current match / total matches.
‹ / › (search)Jump to the previous / next match.
− / + (zoom)Zoom out / in; the percentage shows between them. Remembered per book.
Page indicatorLive current page / total pages, updated as you scroll.
NotesToggle the annotations sidebar (highlights + comments).

Selection popup

Appears when you select text in a page, or when you click an existing highlight.

ActionResult
Color swatchHighlight the selection in yellow, green, blue, or pink.
NoteHighlight and open a comment box for a typed note.
Comment box + SaveAttach or edit a note on the highlight.
TrashDelete the highlight (and its note).

Annotations sidebar

ElementMeaning
Color dotThe highlight's color.
Text + noteThe highlighted text and any comment.
Page NThe page the highlight is on.
Click an entryScroll to the highlight (it flashes briefly).
Trash iconDelete that annotation.

Reading list

ControlAction
Title fieldOptional name; falls back to the file name or URL.
ImportAdd a PDF from a pasted URL.
Upload a PDFAdd a PDF file from your computer.
All / Unread / ReadFilter the list.
Read checkboxMark a book read / unread (updates the dock badge).
Trash / SelectRemove one book, or batch-delete several.

Data & storage

ItemWhere it lives
Books (title, source, read state, last page, last-read time, zoom)IndexedDB records
PDF filesIndexedDB blobs, keyed pdf:<bookId>
Annotations (highlights + comments)IndexedDB records, linked by bookId

Deleting a book also deletes its stored PDF and all of its annotations. Nothing is ever uploaded.

Limits

LimitValue
Maximum file size (import or upload)50 MB
Accepted file typePDF only (validated on add)
Highlight colorsYellow, green, blue, pink
"Continue reading" widgetUp to 5 most recently read books