Skip to content
Case study WhatIsThatBook 2026

WhatIsThatBook: finding forgotten books with SvelteKit and AI

We built WhatIsThatBook with SvelteKit to help readers find forgotten books. We test search changes against known answers and keep working on the cost.

WhatIsThatBook homepage with book-spine navigation and a search form for describing a forgotten book.

The work

We built WhatIsThatBook for readers who remember a story but have forgotten the title. They describe whatever comes back to them and compare the suggested books. We have been building and maintaining the site since July 2025, working on the search as well as the interface.

Visitors and searches

From August 15 through September 13, 2026 (UTC), PostHog recorded 60,725 pageviews from about 20,500 unique visitors on the public site. We counted traffic classified as regular, excluding detected bots, AI agents, and automation. These are measures of site usage, not counts of successful identifications.

In August 2026, PostHog recorded 22,279 saved book searches. This includes follow-up searches and searches that returned no suggestions; the event fires after the search is saved. It tells us how often the search ran far enough to save a result, rather than how many readers found their book.

A bookshop, down to the request form

We wanted the site to feel like an independent bookshop. Book spines form the navigation, and the search form looks like a paper request slip. Warm cream and burgundy carry through the pages. We wanted the form to feel like asking a bookseller for help.

We put those choices in design guidelines, with examples for buttons, cards, and loading states. When we add a page, we can refer back to them instead of working out the design again.

Justin wrote about the design process in Designing web interfaces with Claude Code. The screenshots show how the bookshop reference shaped the navigation and search page.

A real book can still be the wrong answer

The model suggests titles and authors, and we look them up in a book catalog. That tells us which book a suggestion refers to. To learn whether it matches the reader's memory, we ask readers to mark the right answer.

We keep a versioned set of searches with known answers to test changes. Early on, it caught a scoring bug: OpenLibrary sometimes has several records for the same book. We listed the acceptable work IDs for each case so a duplicate record would pass, while a study guide or a different book would still fail.

Some promising ideas failed those tests. Reordering candidates by plot-summary similarity made results worse. Asking the model to write several versions of a query did not reliably improve them either. We saved the experiment records and kept both approaches out of the normal search.

The details are in The two upgrades my eval killed, including the baseline and catalog rate-limit problems we had to untangle before trusting the comparison.

Finding evidence for difficult searches

When the first search returns too few books we can verify in the catalog, a fallback looks for evidence on the web. The model extracts titles from those snippets, and we check them through the same catalog lookup. We discard titles that do not appear in the source text.

We rolled this out behind a feature flag and tracked which candidates it added. We also checked whether readers confirmed those books. Seeing the fallback run was useful, but we still had to find out whether anyone got a better answer.

Lower costs without losing the book

We compared the full search results when testing cheaper model calls. One shorter prompt looked promising until we checked its answers against the catalog and found that it missed books the existing prompt found. We rejected it.

We kept the existing model and prompt and changed how we routed the call. It tries the cheaper Flex service first, allows provider fallback, and makes one extra attempt through standard routing if generation returns no usable output. A valid answer with no matches stops there. We check the results as well as the bill.

Justin published the cost comparisons, including the ones we rejected, in What I learned trying to reduce my LLM costs.

How we built it

The app runs on SvelteKit and Cloudflare Workers. PostgreSQL and Drizzle handle application data, and Statamic holds the editorial content. The evaluation cases and experiment scripts live with the code, ready for the next comparison.

Try the book finder at WhatIsThatBook.

Like this kind of work?

Tell me what you're building. I'll tell you whether a sprint is the right shape, usually within a day.