Daily Archives: August 23, 2026

Building a Library Patrons Choose to Revisit

forward by Mek, Open Library’s program lead:
This year, through Google Summer of Code, the Open Library Team had the privilege of collaborating with Tanishq Sangwan to help readers avoid dead ends and discover more of the books they’re looking for. This collaboration was particularly fruitful because of Tanishq’s strong product sense, his commitment to metrics, and his ability to move quickly from idea to prototype. Tanishq has an impressive ability to cover a lot of ground while consistently bringing thoughtful, ambitious, new ideas to the table. He’s also a clear and proactive communicator, making him an especially well rounded and effective collaborator. I’m excited for the world to see what Tanishq accomplished this summer, and even more excited for countless readers to experience the benefits of his work firsthand.

This year, Open Library published a call for Proposals to tackle one of its most persistent problems: patrons registering, borrowing (or trying to), and disappearing. My proposal, “Personalizing the Patron Experience,” set out to fix that drop off by giving new patrons a taste-driven onboarding flow and a personalized dashboard to land on.

Going in, we thought the gap was mostly about personalization – that patrons weren’t returning because there was nothing tailored to bring them back. Once we looked deeper into the real funnel, instead of assumptions, the picture shifted: a large share of patrons were dropping off way earlier, before personalization could even matter. 

Why now?

In 2023, more than 500,000 books were removed from the lending library. That single event created a lasting mismatch between the value patrons expect from Open Library and the value they are able to access when they show up. A library catalog matters so long as it is useful every time someone visits it – and for a growing share of visits, it wasn’t.

My proposal, built with feedback from my mentors, focused on the post-registration onboarding experience: the sequence of moments right after a patron signs up, when they either find a reason to stay or quietly leave.

Finding a Deeper Problem: A Drop-off Funnel Analysis

Our initial hypothesis was that focusing on the post-registration onboarding experience was the best point of intervention to help patrons connect with more value. Before racing forward and writing code based on this assumption, we evaluated our hypothesis against analytics about the current journey of Open Library patrons.

Our findings from this research helped us shape a revised plan that would ultimately lay groundwork to make our onboarding work as impactful as possible:

1. Patrons fail to find a readable book more often than they succeed.

Analytics show that for every successful “Borrow” click on Open Library, patrons clicked “Locate” twice, attempting to access a book that wasn’t available to borrow. That means patrons who came looking for a specific book were unable to read it roughly two-thirds of the time. This is a problem we needed to address first because no amount of post-registration onboarding will compensate for an initial experience that fails to connect most patrons with a book that is useful to them.

2. Registration itself works against onboarding. 

Before patrons could begin an onboarding flow, they first had to make it through a complicated, high-friction, confusing registration process that brought them to archive.org for activation. Just as bad, the registration process did not remember or preserve the reason a patron registered an account to begin with. In the 1/3 of cases where patrons found a book of interest, they would have to survive a confusing registration process and remember why the registered before accessing that value.

3. Day zero is a dead end. 

After registering, a patron lands on a virtually empty “My Books” page. It’s a ghost-town: There’s nothing to do, nothing to return to, and, unsurprisingly, very few patrons find reason to re-engage after that first visit. This is the crux of the retention problem: onboarding doesn’t fail at signup, it fails in the days immediately after.

Starting with the ability to measure outcomes

Before building any patron-facing feature, we needed a way to actually know whether what we shipped was having a positive impact – not just a hunch that it probably helped. So the first thing built wasn’t a UI feature at all: it was a micro A/B testing framework (#12789) to give the team a way to run experiments and get data-backed answer without guessing.

Helping more patrons succeed

In a library where two-thirds of book clicks are leading to dead ends, the immediate question shouldn’t be how we can optimize for the minority of cases that succeed, it’s: how can we flip the calculus so the majority of patrons succeed. In service of helping patrons succeed in finding books of value to them, we brainstormed four solutions.

  1. Suitable alternatives banner (#12743): For years, book pages on Open Library have had “related books” carousels, buried below the fold. We designed an intervention where, when a patron lands on a book page with no read options, they’re shown a banner with a link to explore similar books that are available to read now.
  2. Offering patrons a “Search Inside” option alongside “Preview” (#12881): Roughly a million book pages on Open Library are preview-only, meaning they cannot be borrowed but patrons can explore a sample of the book. Each of these previews include a “search inside” feature that is useful for researchers, but is tucked away within the Bookreader UI. We prototyped a solution that shows an interactive “Search Inside” button next to the existing “Preview” button. Our hypothesis is, if more patrons knew about the search-inside functionality, then the sum of previews and search-inside actions would be greater than just having the preview button.
  3. Fix the confusing “Locate” button: Several years ago, the Open Library team used to show a grey “Unavailable” button when a book was not readable. Staff hypothesized that it may be more useful to replace this with a “Locate” button that brings patrons to Worldcat where they could see if the book of interest was available in a nearby library. After making this change, many patrons opened support tickets expression confusion at being brought to another site that asked them to register. Furthermore, many international patrons reported that Worldcat had no availability options that were relevant to them. As a result, we decided to replace the “Locate” button with a “Check options” button that brings them to the Open Library book page, and then to show an explicit “Worldcat” button in case the patron wants to check nearby libraries. The benefit of this change is that more patrons will see the “Suitable alternatives” banner and have more access options to choose from, such as buying the book should they choose. We currently have a prototype of this change and are in the process of collecting feedback from the community.
  4. Consolidating “Buy” options (#13113, #12914): The sidebar was scattered, with multiple CTAs for books. These were unified into a single, clean “Buy” dropdown so the interested patrons can easily access all purchase options, while uninterested patrons aren’t overwhelmed by this information.

Fixing registration so every success counts

For many years, after a patron signed-up, they would receive an activation email that redirected them to archive.org and then required them to return to Open Library and then login. This process was confusing because it spanned two domains. During our collaboration, Mek switched this flow so that activation emails brought you directly to Open Library and automatically logged you in. But what then?

Prior to my work, the registration process would forget the action the patron was trying to accomplish, making success less likely. To address this problem, I designed a banner (#9409) that remembers a patron’s registration intent and allows them to seamlessly continue after they’ve registered. Since implementing this feature, more than 10% of registered patrons choose to use this to continue where they left off.

Giving patrons reasons to return

As a result of the above interventions, we expect our metrics to show a greater percentage of patrons are succeeding to connect with book they love — whether that’s taking advantage of search inside, finding suitable alternative books when their first choice is unavailable, or having a registration process that works with them instead of against them.

The final step (and our initial goal for GSoC) is to give patrons reasons to return. This means every time a patron visits their “My Books” page, they should encounter value. We outlined two efforts that dovetail with our original onboarding plans:

  1. The “Continue Reading” carousel: a consolidated view of books the patron may wish to continue reading.
  2. The “Build Your Library” section: a collection of ways for patrons to add books to their reading log.

We were able to complete the “Continue Reading” initiative during the course of GSoC. We produced specifications and mockups for the “Build Your Library” phase, which we plan to continue working on as follow-ups.

The “Continue Reading” carousel (#13256)

Over the past several years, the Internet Archive has moved from a default two-week loan period towards more flexible and equitable models that allow patrons to borrow book for the duration of session, so long as the book is being actively used. On one hand, this means fewer patrons are leaving books sitting unused on their digital desks. On the other hand, it means going to your “My Books” page is less likely to show active loans to continue reading. To address this problem, we’ve been building a “Continue Reading” carousel with two phases:

  1. Phase I: Merge Active Loans & Loan History (#13272).
    • Because many loans expire after about an hour and then vanish into a separate history table, this phase makes it so that both your active loans and your loan history get merged into a single coherent view, making it easier for you to continue reading where you left off.
  2. Phase II: Enhance “Continue Reading” by adding open-access books (#13273, #13274).
    • One gap of our current system is that open-access books don’t get recorded under loan history and so never show up under your My Books page. Similar to our “recent searches” history, we’re first using local storage and then exploring a dedicated database table to help patrons keep track of the open access books they’ve began reading. We intend for these settings to be manageable via the loan / reading history page.

Next steps: The “Build Your Library” section (#13255)

After GSoC, we plan to continue development on the second phase of improvements for the “My Books” page, to give patrons clear calls-to-action and new experiences for adding books to their library. The goal it to give patrons the tools to, “Make Open Library Your Library“. Rather than designing a blocking onboarding flow that is only done once or even skipped, we decided to try adding a section to the My Books page that increases discovery of our import options (Goodreads, barcode scanner, search) so that patrons can add books any time they visit their library. As more patrons use these import options and grow their reading logs, their activity contributes towards book discovery for everyone. The library grows not just through its books, but through the collective reading experience of its readers.

The idea of the new “Build Your Library” section is to meet patrons where they already are, based on which of three groups they fall into, and give each a seamless action to bring their reading into Open Library at once rather than book by book:

  • New readers: a flow to explore genres and bulk-add books to shelves and lists directly from that exploration, instead of searching for each book individually, opening its page, and adding it one at a time.
  • Readers with a library elsewhere: the import tool already exists but is underutilized. This means improving that experience and expanding it to cover other popular platforms, so a patron can export from wherever they already track their reading and import straight into Open Library.
  • Readers with a physical collection: the barcode scanner already exists but is underutilized too. This means improving it for bulk scanning, so a patron can log a shelf of physical books in one sitting instead of one at a time.

How patrons discover what to add next, how shelves get organized and recommended, and how the page evolves as a patron’s reading history grows are all part of this epic too. This is the epic I’d point a future contributor toward first.

This unlocks two things down the line. Once patrons have a real library instead of an empty shelf, there’s finally enough signal to build genuine recommendations – curated to taste, not generic – since bulk-adding from these three flows is what generates that signal in the first place. It also revives the existing activity feed, which is underused today for the same reason: it only has something to show once patrons are active. As more patrons bulk-add their libraries, the feed becomes more valuable to the whole library.

Impact

Already, several of our interventions have improved the experience of thousands of patrons across the Open Library.

  • Preserve Intent banner: ~500 clicks/day against total shown, a ~12% click-through rate – patrons redirected through registration are following the banner back to what they were originally trying to do.
  • Preview / Search Inside visibility: ~13,800 previews and ~1,100 Search Inside opens per day since the buttons became more prominent.
  • Unavailable-book alternatives banner: ~2,500 clicks/day, patrons routing to a readable alternative instead of a dead end.

Having fun along the way

One of the parts I enjoyed about working on Open Library was the autonomy to work on features that I thought were useful. One example was the “Stopped Reading” bookshelf (#12400) that many patrons had been requesting for years. There was another case where I took the initiative to improve the design the highly visited “My Loans” page (#12912) to make it easier for patrons to navigate their books.

What I’ve learned

The instinct going in was to treat this as a personalization problem – better empty states, taste capture, recommendations. Open Library already has plenty of features like that, loved by a smaller set of patrons – it’s easy to keep adding to that pile. The funnel numbers pushed me to stop designing from “what’s a good addition” and start from the patron’s actual seat: what’s stopping them from getting anywhere at all? That shift mattered more than any single feature – it’s why the summer became about removing friction patrons were already hitting, not adding something new to discover.

Looking back, a lot of the highest-impact work shared the same idea: don’t ask patrons to do something new, save what they’re already doing. Preserving intent through registration (#9409) means a patron who clicked “borrow” doesn’t have to re-find that book after signing up – we just remember what they were already trying to do. The Continue Reading epic (#13256) applies the same idea to reading itself, picking up on what a patron’s already reading instead of asking them to curate a shelf. Neither asked patrons to learn something new – they just stopped losing track of what was already in motion.

I also came away with a much better appreciation for measuring before shipping. We didn’t get to actually run experiments through the A/B testing architecture yet, but having it in place – ready to give real answers instead of hunches – is something I’m genuinely excited to put to use.

Finally, I’m proud that we we’ve been able to move quickly and prototype many features that span the patron experience, however, with a large open source project, it’s been a learning that we can only move as quickly as the review process and the feedback we’re able to get from the community. There are several efforts are in review or mid-flight, worth tracking post-GSoC:

  • #13113 – Consolidating buy options (open)
  • #12914 – Locate → Check WorldCat options (open)
  • #13281, #13282, #13283 – the three Continue Reading phases (all open)

None of this ends with GSoC. Both epics – Continue Reading and Build Your Library – are far from done, and I plan to keep working on them past the program, seeing the remaining phases through rather than leaving them as a hand-off.

Acknowledgments

Thank you to my mentor, Mek Karpeles, and the Open Library staff and community – they’ve been extremely helpful and supportive throughout, even before GSoC. The drop-off funnel analysis that shaped nearly every decision in this project came out of that early framing, and the steady feedback across a summer of shipping into a live, high-traffic library catalog made all of it possible.

A special thanks to Lokesh Dhakar and Ray Berger, who encouraged and supported me in getting started with Open Library back in February – which eventually led to spending the whole summer building with the team.

Helping Patrons Discover Books

A forward by Mek, Open Library’s program lead:
This year, the Open Library team and I were fortunate to collaborate with Chisom, as part of Google Summer of Code, to make millions of books more discoverable to readers. Chisom entered this year’s Google Summer of Code program a motivated and capable software developer and continued to impress us with her focus, proactivity, and problem solving. It was a joy working with Chisom and rewarding to witness her make consistent forward progress, rise to growth opportunities, and — as a result of hard work and initiative — achieve an excellent outcome that I believe will benefit millions of Open Library patrons. I encourage you explore how she strategically approached this challenge and created a general purpose tool and patterns that will allow others to continue her work into the future.

My name is Chisom Nnamani, and this summer I had the opportunity to join the Internet Archive’s Open Library team as a Google Summer of Code (GSoC) contributor. This was my first experience contributing to a large open-source project, and I could not have asked for a better place to start. As someone who cares deeply about making books accessible to everyone, I was drawn to Open Library’s mission of providing a free webpage where anyone, anywhere can discover and access published works. You can view my initial proposal here.

My GSoC project focused on a problem that sounds simple at first: helping readers find books by genre.

Millions of books available, the challenge is discovery

Over the years, Open Library has accumulated millions of free-form book labels that have never gone through a standardization process. As a result, a book about science fiction might be labeled “science fiction,” “science-fiction,” “sci-fi,” “scifi,” or dozens of other variations. Without a way to recognize and merge these synonyms, books become scattered across hundreds of different labels like a needle in a hundred haystacks.

Search termResults returnedBooks missed vs. best
“Science Fiction”17,900 hits— (baseline)
“science-fiction”16,497 hits~1,421 books
“sci-Fi”2,721 hits~15,179 books

The result shows how a reader can miss hundreds or even thousands of books simply by using a different term to describe the same genre. The books are there. The problem is that the catalogue does not always connect them.

Messy labeling means messy recommendations

The problem goes deeper than the search box. For years, Open Library has used a subjects field to describe what a book is about. These subjects are stored as plain text strings in a flat list, with no consistent rules about how they should be written or organized.

As a result, different kinds of information can end up sitting side by side. A book can have its genre, characters, places, themes, and other descriptions all represented as separate subject strings. There is no structure telling the catalogue how these descriptions relate to one another.

The screenshots below show what this looks like on real book pages. The Hobbit has “Fantasy,” “Fantasy fiction,” and “Juvenile fantasy fiction” as separate tags on the same page:

Figure 1: The Hobbit’s subjects include multiple variants of “fantasy” with no major classification.

The screenshot below shows another example: And Then Were None has over 30 subject tags with no structure distinguishing genre, subgenre, language, audience, character, and other types of information. You can also see multiple variations of “mystery,” including “Mystery fiction,” “Mystery & Detective,” and “Fiction, mystery & detective, general.”

Figure 2: And Then Were None — 30+ subjects with no type distinction between genre, subgenre, language, audience, character.

Together, these examples revealed the larger problem I wanted to address. Open Library had a huge amount of useful information about its books, but it lacked a consistent structure for connecting related genres and descriptions.

That became the starting point for my GSoC project: building a more structured way for Open Library to describe books by genre and subgenre, and eventually using that structure to make browsing and discovery better for readers.

The recipe for organizing 860K books

When I began GSoC, the Open Library team had already identified several high-impact label categories (tag types) that could benefit from this kind of cleanup, including genres and subgenres, audiences, content warnings, and formats. What we didn’t yet have were mappings from our existing messy labels to these new, cleaner categories, or a common software framework that contributors could use to define these mappings and perform the cleanup.

I began by working with genres and subgenres. The first step was to define the categories we wanted to recognize. We then needed to connect the many ways these concepts already appeared in Open Library’s catalogue to a consistent set of canonical labels – the standardized labels we want those variations to map to. For example, different subject descriptions might refer to the same genre using slightly different wording or formatting.

From there, I worked on expanding and refining the mappings so that more of the catalogue’s existing subject descriptions could be connected to the appropriate genres and subgenres.

But the goal was not to build something that only worked for genres. As the project evolved, we built a common core that could support different types of labels through the same process: define a vocabulary, create mappings, analyze existing data, and eventually migrate the cleaned information back into Open Library.

This separation between the tag type and the shared tooling became an important part of the project. Genres and subgenres were the first categories I worked on, but the same framework can be used for other categories as contributors begin cleaning and structuring them.

Here’s what that mapping looks like for a few genres:

Existing subject strings on Open LibraryCanonical genre
“Fantasy”, “fantasy fiction”, “Juvenile fantasy fiction”Fantasy
“Mystery fiction,” “Mystery & Detective,” “Fiction, mystery & detective, general”Mystery
“Science fiction,” “science-fiction,” “sci-fi,” “Science Fiction Literature”Science Fiction

Several different subject strings can now point to the same canonical genre.

Once these mappings were in place, the next step was to give each canonical label a structured representation in Open Library. In the Tags project, a Tag is an Open Library data object representing a defined label, such as a genre or subgenre. This gives the canonical concept its own consistent identity instead of treating every variation of a subject string as a separate concept.

I then created the canonical Tags for the genres and subgenres we had defined.

Fantasy, now represented as a genre Tag in Open Library, rather a plaintext subject string.

Steampunk, a subgenre represented as a Tag.

With the genre and subgenre labels defined and represented as Tags in Open Library, the next challenge was connecting them to the millions of existing works in the catalogue.

Open Library already had millions of works with years of existing metadata. I could not simply assign these new Tags manually to every work. The next challenge was figuring out how to connect the information that was already there to this new structure, and then safely apply those connections across the catalogue.

So I built migration tooling that could analyze existing subjects, identify matches using the genre and subgenre mappings, and connect those matches to the appropriate Tag keys on each work.

Before thinking about millions of records, I first needed to understand what the migration would actually find. I ran the matching process against Open Library’s April data dump, a monthly snapshot of the catalogue’s data, and found 869,461 works with genre matches and 51,526 works with subgenre matches.

Those numbers changed the way I thought about the project. This was no longer just about creating a better vocabulary. It was about applying that vocabulary across millions of works while making sure the information already there was not accidentally changed or lost.

I worked on the migration scripts, the shared utilities behind them, and the changes to Open Library’s work schema needed to store the new genre information. I also validated the migration on a smaller pilot before moving toward the production run.

Safely running a large-scale migration

One of my biggest lessons from this project was that writing the code is only part of the job. When you are changing a large, live system, you have to think about what happens when the code actually runs.

  • What happens if something fails halfway through?
  • How do you know the migration did what you expected?
  • How do you avoid changing records that should not be changed?
  • How do you test an operation that will eventually touch hundreds of thousands of works?

I used dry runs and small pilots before larger operations. I added ways to track progress and designed the migration so that it could be run in controlled batches. Along the way, I also encountered some of the less glamorous parts of working with production systems, from authentication and request limits to unexpected differences in the data itself.

One of my favourite lessons from the project is that production engineering requires trust.

Before you can make a change at scale, you have to earn the right to trust your own tools.

Translating better data into better discovery

In our GSoC project, fixing book labels was always a means to an end: improving how readers discover books. Many patrons come to the Open Library looking for a specific book. But not every reader arrives knowing exactly what they want to read next. With consistent genre data in place, we could begin to ask a different question:

What if readers could browse and discover books by genre instead of having to already have a book in mind?

Search and filtering can help when you already know what you are looking for. But discovery is different. Sometimes you just want to browse.

That question became the idea behind Genre Explorer.

Taking inspiration from Drini Cami’s Library Explorer – a system that uses Dewy Decimal classification numbers to digitally emulate the organized bookshelves of a physical library – we imagined a more visual way for readers to explore the Open Library’s book catalogue, using the same genre and subgenre structure I was building for the tagging project. Instead of presenting genres as another long list of links, we imagined something closer to the experience of walking into a bookstore.

Genres could act as bookcases.
Subgenres could become shelves.

A reader could choose a genre, step inside it, explore its subgenres, and discover books along the way. The idea was to make genre browsing feel less like searching through metadata and more like browsing a library. I developed the initial concept and built a clickable prototype to explore how this experience could work.

From there, Mek and I continued developing the idea together. We reviewed the experience, explored how it could fit with Open Library’s existing components, and refined the concept into an interactive version now available on the testing site.The interactive version follows the same idea: genres act as bookcases, and entering a genre reveals its subgenres as shelves.

What I find most exciting about Genre Explorer is that it grew out of the original tagging problem, but takes the idea one step further. The canonical Tags give Open Library a consistent way to describe books. That structure can support better search and filtering, while Genre Explorer explores what it could look like when the same information is used to help readers browse.

It was an unexpected direction for my GSoC project. I came in focused on the data and infrastructure behind genre information. Along the way, I started thinking beyond how books are described to how that work could become something a reader actually experiences.

Takeaways

When I started this project, I expected to learn more about software engineering. I did, but not always in the ways I expected.

One of my biggest lessons was learning to slow down and understand a system before trying to change it. I learned to look at messy data and find the patterns hidden inside it, to test my assumptions against real examples, and to treat small experiments as part of the engineering process rather than as steps before the “real” work begins.

I also learned to think beyond the implementation. Throughout the project, I kept coming back to a simple question: Does this actually make the experience better for the person using it? That question shaped how I thought about the tagging system, and eventually led to the idea of Genre Explorer. It reminded me that good engineering is not only about building something that works. It’s also about understanding if and why something should exist in the first place.

Working with Open Library also gave me my first real experience contributing to a large open-source project. I had to learn how to navigate an unfamiliar codebase, communicate ideas clearly, ask questions when I was unsure, respond to feedback, and make decisions when there was no obvious answer. I was not doing this work in isolation. My mentor, Mek, pushed me to think beyond the code and focus on the larger problem we were trying to solve. Open Library contributors and maintainers, including Jim, Drini, Liz, and Katrina helped me understand different parts of the systems I was working with. Every review, discussion, and debugging session became part of the learning process.

Looking back, I think that may be one of the most valuable things I am taking away from GSoC: learning how to become useful in a system that existed long before I arrived.

Next steps

By the end of GSoC, we were able to add genre tags to more than 50,000 works. We also built common infrastructure to standardize the tag migration process and enable others to contribute to the greater cleanup process.

The next stage is to extend this process to add subgenre tags to works and to index these genre and subgenre tags in Open Library’s search engine, so readers can find and explore books by genre.

Genres and subgenres are only the beginning. Open Library has other high-impact label categories that will benefit from the same approach, including audiences, moods, content warnings, and content formats. Because we built this project to have a shared core for defining vocabularies, creating mappings, analyzing existing data, and migrating cleaned information, future contributors can use the same tooling to work on these categories rather than building a new system from scratch.

This shared core is the legacy I hope will last beyond this GSoC project: not just cleaner genre and subgenre data, but a reusable foundation that makes it easier for Open Library and its contributors to continue turning messy catalogue labels into structured information that can improve how readers discover books.