M2Mar 14, 2026

The catalog is a source, not a store

by Aliyah Daleen

The catalog feature lets you browse free OPDS feeds — Project Gutenberg, Standard Ebooks, any feed you add yourself — and pull a book straight into your library through the same import pipeline as a file from disk. We built it, and tested it, against committed test fixtures first, the way you'd test anything. Then we pointed it at the real feeds, and it immediately found two bugs the fixtures had no way to know about.

Current catalog design with discovery shelvesCurrent catalog book details and external retailer offer
The catalog has since changed direction: today’s Slint design uses eBooks.com and external checkout. The March article below records the earlier OPDS implementation. Titles, availability, and prices shown here are fixtures, not live offers. Select an image to view it full size.

Project Gutenberg's front page isn't a list of books. It's a navigation feed — its entries are shelves like "Popular" and "Latest," each one a link to another feed, not a link to an EPUB. Our parser had no concept of that distinction, so it read every shelf as a book with no downloadable file and rendered Gutenberg's entire front page as a wall of "Not an EPUB." That's exactly the impression of a broken catalog we didn't want to give, so entry parsing grew a navigation case — reached only when an entry truly has no acquisition link at all — so a shelf reads as a shelf instead of a row of failures.

The second bug was subtler. Gutenberg's most-popular shelf is itself a list of books, but each entry in it links to a further, per-book feed rather than directly to a file — real two-level OPDS 1.x, which our fixtures hadn't modeled. Treating those as plain navigation links would have turned a shelf of Austen and Melville into a row of grey "browse" pills with no titles worth reading. Entries stay rendered as full book cards regardless of whether they're immediately downloadable, because the alternative actively hides the thing you came to look at.

Standard Ebooks handed us a different kind of honesty problem. Every one of its OPDS endpoints now answers with an authentication challenge — the books and the account are both free, but the feed itself is gated. The easy wrong move would have been to present every Standard Ebooks entry as a normal one-tap download and let it fail on the first tap. Instead those entries carry a flag saying they need authentication, and say so up front, before you waste a tap finding out.

One more decision worth naming: fetching OPDS feeds happens in Rust, not in the webview. That's not a style preference — public OPDS servers don't send CORS headers, so a plain webview fetch against Standard Ebooks fails before a single byte comes back. Parsing stays in one shared package regardless of which platform is asking, so the rules about what's actually safe to import — no DRM, no paid acquisition types treated as free — exist exactly once, checked against committed fixtures, rather than being re-implemented (and re-diverging) per platform.

Every download gets checked twice before it's treated as a book: once by declared content type, once by the actual ZIP file signature. A filename or content type that arrived over a feed is untrusted input, the same as a file dropped in from anywhere else — the catalog is a way to find your next book, not a reason to trust it more than one you downloaded yourself.

← All devlog posts

The cast has been waiting for you.

Join the waitlist — beta invites go out in order, and the devlog keeps you honest company until then.