How I built my AI powered book insights app
Tags: mobile, ai, learning, reactnative
Published: 2023-10-17 18:35:27

### Brief introductions

Hi, my name is Brett Thurston. I'm a developer and maker who enjoys working in the front-end spectrum of development and design. I've made an app and wanted to recap some highlights and lessons learned from my journey so far. I'd like to post more frequent updates on working on Book Scout.

I hope this will interest you, the reader, and encourage you to share your journey in creating something, too. This isn't meant to be a tutorial, but more talking about the process and knowledge gained.

### What did I just buy?

My 15-year-old daughter and I were at a bookstore recently. She picked up a book she remembered her friend was reading and recommended to her. I took a look at the cover and read the blurb on the back of the book. After a passing moment I said, sure we'll get it. I purchased the book then and gifted it to her. On the way home my wife and I had a sneaking suspicion that the book probably deserved a little more investigation. After 30-45 minutes of researching Amazon reviews, Goodreads, and Common Sense Media it was decided that the book purchase was a mistake. The book was way, way too spicy (and dark) for what we believed was acceptable for her age. It pained me to return the book, but after explaining to her she agreed, that it was not the book for her, anyhow.

At that moment I thought about a few things:

* **Why can't books come with some movie-like-rating system?** Slap a sticker on there that says PG-13 and we're good to go. Rated R? May have to look into why it's rated R.
    
* **Why can't consumers have easier means to figure out if a book is for them or not?** I'm an avid reader myself and have spent countless hours over the years on Goodreads, Amazon reviews, and Reddit trying to decipher if a book will speak to me in ways I appreciate. For instance, I'm a big Fantasy fan, but Grim Dark is not my cup of tea. Give me the cheesy 90's fantasy books like Dragonlance any day of the week over Game of Thrones.
    
* **What if I could have an infinite source that gives me just pertinent info on themes in books?** I'd like to know what positive/interesting themes are in books, as well as questionable themes (like trauma, dark content, etc...). Furthermore, it'd be nice to know if a book hangs its hat on using common tropes that I'd like to avoid. Wouldn't it be nice to know ahead of time if a book has something in it that puts it on the Did Not Finish List for me? Especially before I get halfway through it?
    

### Light bulb moment

That is where I had the idea for [Book Scout](https://bookscoutapp.com). I wanted to build this tool that could answer these questions for me and my family. If others benefit from it, then fantastic! If not, at least I have a project to work on and find some fulfillment in.

And so now you're reading about this moment in my life. I think it may help us both to learn from one another how this app was built, what the process was, and the challenges I found along the way. I suppose you could call this a built-in-public type of post, but the app is already built and available to take for a spin. [You can download it now at the Apple App Store.](https://apps.apple.com/us/app/book-scout/id6466491163) I'd be interested to hear your feedback on the app. It's not perfect, but it's usable. It's a start.

So if you're interested in reading about process and mistakes made and victories end, read on friend!

Have you built anything that solved a problem for you, your family or friends? Let me know in the comments below, please. :D

### First things first: can the core feature work?

Before I did a stitch of coding or a lick of design I knew I had to find out if I could get AI to do what I needed it to do: give me positive and negative insights on a book. I spent a few nights after work crafting up a prompt with [ChatGPT](https://chat.openai.com/). I checked out [Bard](https://bard.google.com/), but after comparing the results, I was happier with the ChatGPT experience. Not to mention, I couldn't get access to the Bard API.

After getting my prompt, I had a hook. It worked. I was pretty impressed with what ChatGPT was able to give me in the data returned. This hook would be the thing that would make a user come back for more.

As an avid reader, I threw a lot of books that I've read to see how reliable the insights given were. And as it turned out it was very reliable. The themes it highlighted were found in the books that I read. Wow, so this could work.

### Proof of concept

Pardon my brief sidebar into [React Native Expo](https://docs.expo.dev/tutorial/create-your-first-app/): I've built React Native apps before, but never with Expo. Expo has come a long way since I first started working with React Native, which was back in early 2019. After reading up on Expo I found that it still handles a lot of the binary native stuff related to mobile app development. And ejecting out of Expo was a big topic back in 2019/2020 but now you don't have to eject out of it since it has the prebuild feature. This essentially builds the rest of the project out as if it were a full-on React Native project. Expo isn't without it's limitations, but I liked that I could focus more on the app and less on the scaffolding of it. So far it hasn't presented a lot of limitations for this project. Expo has a ton of libraries available to help tap into the native features of devices.

Projects that rely heavily on native device features and work with the native code will have a harder time with Expo.

So I spun up a React Native Expo project. I started making API calls to ChatGPT to see if I could give it a book title and author. And I got the insights that I wanted. Everything then started flowing into prototyping the UI for an app idea. I chose React Native Paper since it's a React Native component library powered by the MUI component library (a favorite of mine). Now I could begin building a core version of Book Scout.

### API

I wanted to display metadata for the book you would search for. I started using both Google Books API and a web scraping method I found using Cheerio and Axios on Amazon product pages. [You can read more about web scraping here at FreeCodeCamp.](https://www.freecodecamp.org/news/how-to-scrape-websites-with-node-js-and-cheerio/)

I gotta say, hats off to those who web scrape regularly because it sometimes can feel like a needle in a haystack finding the right class selector for DOM elements - PLUS making it consistently selected. I started drafting in my React Native app this page of book details and insights. It was a combination of ChatGPT, web scraper and Google Books API call. It was messy. The web scraping factor produced very inconsistent results.

After a few days of trying to make this setup work, I decided to focus on Google Books API and ChatGPT API calls. Amazon offered cool data like related books, popular highlights (quotes people often highlight in their Kindle app), author bios, recommended books, etc... Looking back it was a good call to start small and have a sturdy foundation. An app should do the thing it advertises well every time the user uses it. If not, trust erodes and usage is hurt.

### Taking advantage of mobile device features

After some time crafting a page to capture insights and metadata about a book I began to wonder, what about this app makes it worthy to be an app? Naturally being available on a mobile device is one advantage. But that was all I had at the time. That led me to think well, this could just be a website. And that's true, it could be. But thought back to that day with my daughter in the bookstore. What if I could use my device to capture the book I wanted insights about quickly? Of course, we'll use barcode scanning in the app. [Fortunately, Expo had a library just for that](https://docs.expo.dev/versions/latest/sdk/bar-code-scanner/).

Now I was able to make a modal in my app, scan a barcode and use the ISBN to search Google Books API for the metadata. Sweet! I was scanning newly published books, but then I realized older books I was getting two types of errors from Google Books API. The first would be an error where the ISBN given returned a different book. The second error was nothing was returned from the API to Google Books, period.

After some research, I realized the ISBN and the UPC don't always match up. A lot of newly released books seem to match the two, but in older books, especially, you'll find the ISBN and the UPC are different. So where I thought I was sending Google Books API my ISBN, I was sending my UPC. Oof.

So now, I have to capture this use case in my bar code scanning feature. Otherwise, users won't have a seamless experience. So I thought, OK, we could show a modal that explains the ISBN didn't validate (meaning it was a UPC scanned). This modal could give the user the option to input the ISBN themselves or redirect the user to the Search feature. That worked well I thought and it's in the app today.

It was a good exercise in moving beyond happy paths in app design. Because what's true for you won't always be true for every user and use case. My goal for v1 of Book Scout was to make sure there was at least a consistent experience despite all the use cases of searching or scanning books. I'm positive I have more use cases to capture, but they, to me, feel like very fringe use cases that won't impact the average user.

That's why it's good to ship and iterate. Let your users help surface problems to you so you can address and fix them. Also, you won't sink a ton of time and resources into problems that aren't problems to your users.

### Cache money, baby

Speaking of moving beyond the happy path, I was also thinking about scaling this app at the foundations. That's why I chose to use [Firebase](https://firebase.google.com/) to cache data created by API calls to return to users instead of making API calls to ChatGPT or Google Books API on every request. Caching data not only returns data faster for your users but can save on the cost of operating the project.

So using Axios, I made an instance for each type of vendor I was using with initial headers set up. Then I created methods that checked Firebase for data before actually making the call to the vendor. This proved to be fruitful to begin with.

The only gotcha I've seen is if you change the shape of your data, you'll need to wipe your old cache or adjust it to fit the shape you land on. It does not have a major impact on users if you wipe your database cache data, but could be expensive at scale.

Do you have any advice on caching data or stories to share with your app? Please let me know in the comments below!

### Bookshelves

So to review, I've got an app that can search or scan for books and render book insights and metadata. This was an acceptable POC, in my opinion. I wanted to set my focus on delivering version 1. Something I can ask you to look at and you feel this is a whole product and not just a POC. I needed a minimal viable product.

The app felt fleeting though. Like you scanned something, but that's it. What if users want to keep track of what they've scanned/searched for or even categorize those books into traditional reading buckets like 'Reading' and 'DNF' (Did Not Finish)?

Throughout this project, I wanted to make sure I was studying book apps. I wanted to make sure I wasn't reinventing the wheel or solving problems that I don't need do if I just shifted left a little on approach. GoodReads lets you shelve books. Why couldn't Book Scout users do the same?

So I created a history of books viewed and a book shelving system. The shelving system has 4 categories:

* Reading
    
* Completed
    
* Want to Read
    
* Did Not Finish
    

In the future, I'm going to allow users to share their shelves with others, back them up into a cloud account of theirs and create custom shelves.

Customer reviews for books

Another feature I wanted to add was to grab the Amazon customer reviews and display them in the app. And after I did it, it didn't feel special or unique enough of a feature. Sure, it could help inform a user, in addition to the insights, what others were saying about the book, but what I wanted was to create keywords to track in the customer reviews. If the customer review had a keyword in it that I was tracking, highlight it for me.

For instance, if I set the following keywords:

* violence
    
* gore
    
* murder
    

Then any customer reviews that came in for a book that had those words in them would be easily identifiable in the app. The app itself doesn't care what your sentiment is around those keywords. I think this is a nice service for those who have experienced some sort of trauma in their life and may not want to read about it in their books.

### Content moderation

One thing that popped up in the beta phase was user-generated content. As a solo founder and developer I don't want to be responsible for moderating reviews my users create. At least not yet. I'm happy to pass that off to Amazon and their team to moderate the customer reviews.

I'm keeping an eye on comments though and making sure I'm not seeing anything that would be unfit for a public app.

Are you a solo developer with an app that has user-generated content? If so, how do you manage it? Let me know in the comments below.

### Theme and Presentation

A lot of the visual notes were created with MidJourney. I never really got into generative AI, but working with MidJourney has been fun. I learned how to create prompts and tweak images to use in the app. I wanted to create the ambiance of discovering something new for the first time. To me, the works of Studio Ghibli and fantasy literature evoke that feeling. And that's what this help, I hope, can help be a part of with the experience the users are looking for: the feeling of finding something new and wanted.

### Beta phase

So I had a working app that I was now ready to get feedback from someone. I focused on the iOS platform first since a lot of people I know have it. Ironically, I'm an Android user, but I own and prefer my Macbook. There are probably, literally 10's of us out there.

So I set up my App Store Connect with Apple. [You can read more on what that is here.](https://developer.apple.com/app-store-connect/) Then I used 'eas build' from Expo to bundle my app for me. Then I used Transporter to send the bundled file (.ipa) to App Store Connect. After that, I made a beta group and invited a lot of my close friends and family to test the app out on their iPhones. I got some good feedback from that and added much-needed polish like loading states and further optimizations to API calls.

Eventually, I got to the point where a strong version 1 was there. After 2 months of lots of late nights, I was ready to submit to Apple for approval.

And I got denied on my first submission, haha.

What happened was there was a button on the book page that found the book on Amazon and linked it directly with a tag in the URL related to my Amazon Associates account. Apple isn't keen on allowing their users to purchase things outside of their in-app payment system. So I removed the direct link button to the book you were viewing button and it was approved! Huzzah!

### Social marketing for this app

I'm not a strong social media user. I've tried in the past, but I think, like many people of my generation (elder millennials), I want to exist in a small, trusted niche community. I don't have a TikTok, I used to post on Twitter a lot, but it was Tech Twitter and just an attempt to learn, develop clout and build community. I deleted my Facebook about 5 years ago and haven't missed it. Facebook groups were nice though. I digress.

So how does a non-social media person tell others about their product? I'm in the middle of that process right now, but I plan to focus on Instagram right now. Bookstagram is a big thing there. I haven't had the opportunity to put the gas on posting content, but there are posts there. [You can see the Book Scout Instagram here.](https://www.instagram.com/getbookscout/) Give me a follow if you'd like!

My plan for social content is a few things

* Post sample insights from the app
    
* Post things about the app
    
* Post bookish things (have yet to do)
    
* Post generative art about made-up short stories (filler content)
    

I don't have much to say about this part of the process other than consistency wins and it's hard to do that solo, lol. Eventually, I'll wise up and consider hiring someone to talk about Book Scout, but for now, I'm making due.

What I do feel though is nobody is going to know about your product if you don't talk about it. So I'm finding out what that looks like now. Future posts on this, there will be, I'm sure.

### Summary

Thanks for reading this recap of my day 1 to day 62 with version 1 of Book Scout. I have a lot of interesting optimizations and features in the works for the app. I hope that it can be a service to those readers who are curious about what's in the next book they want to read.

The next phase is to start to understand a target audience to help the app grow. The target audience will not only help refine the app but also inform me about where to go and what to do next (aside from my itinerary).

I hope that sharing my journey so far can help inspire or encourage you to go and build that thing you've always wanted to build. The projects we make will not be loved by all and may not make it to superstardom, but there is a sense of accomplishment and fulfillment I get with working on Book Scout that I haven't found elsewhere as a serial entrepreneur.

And speaking of entrepreneurship, depending on the market fit of this app, I'll need to think of how to make this profitable beyond mobile ads. But that is a tomorrow problem that I'll address another day.

If I could do it differently, I would have focused on the core feature first and worked with the minimum amount of API vendors possible. There was a stretch there where I didn't know what I wanted to get out of the API calls. I think when you limit yourself, it's easier to prove a concept instead of juggling a lot of balls to get the vision established.

Thanks for reading again and I'm looking forward to posting more about the process in the future.