Under the Hood - Why Booklynx Uses NoSQL
When building an app like Booklynx, one of the first decisions I had to make was: "Where do I put the data?" The answer shapes everything from how fast your library loads to whether you can use the app offline.
For decades, the standard answer was a "Relational Database" (SQL). Imagine a giant Excel spreadsheet where every book must have exactly the same columns. If I want to add a "narrator" field for audiobooks, I have to change the whole spreadsheet structure.
For Booklynx, I chose a different path: NoSQL (specifically, Google's Firestore).
What is NoSQL?
Instead of a rigid spreadsheet, imagine a massive room filled with file cabinets.
- Users are one cabinet.
- Books are another.
Inside the "Users" cabinet, there is a folder for you. Inside your folder, I can put anything I want. I can put a sub-folder called "My Library" and just toss documents in there.
If one book has a translator and another doesn't, it doesn't matter. NoSQL is flexible.
Users Collection
- • Profile info
- • Settings
- • Preferences
Your Library (Subcollection)
- • Books you own
- • Reading progress
- • Personal notes
Social Data
- • Friends list
- • Activity feed
- • Reviews
The Benefits
1. Speed
This is the main reason. In a traditional database, if you want to see your library, the computer might have to look at the "Books" table, find the ones that match your ID, then look at the "Authors" table to get the names, and stitch it all together.
In my NoSQL setup, I store your library inside your user folder. When you open the app, it just grabs your folder. It's one trip. This is why your library loads almost instantly.
The Result
2. Offline Capability
Because the data is structured in these neat little "document" packages, it's very easy for your phone to save a copy. This means Booklynx works great even when you're in a subway tunnel or on a plane. You can still browse your library and update your reading progress.

The Trade-offs
Transparency is key
1. Data Duplication
In a spreadsheet, you write the author's name once. If they change their name, you update it in one spot.
In NoSQL, to make things fast, I might copy the author's name onto every book review you write. If that data changes, I have to go hunt down all those copies and update them. This is a complex background task I have to build carefully.
2. Complex Queries
Asking "Show me all users who have read The Hobbit" is harder in NoSQL because the data is hidden inside everyone's private folders. I have to build special "indexes" (like a library card catalog) to make these searches possible.
// Firestore requires indexes for complex queries
// This lets us search across all users' libraries
const booksIndex = {
collectionGroup: 'books',
queryScope: 'COLLECTION_GROUP',
fields: [
{ fieldPath: 'googleBooksId', order: 'ASCENDING' },
{ fieldPath: 'addedAt', order: 'DESCENDING' }
]
};Recent Changes
I recently refactored the database to move your library into what I callSubcollections. Previously, all user books were in one giant pile. Now, they are strictly nested under your User ID.
This improves security (it's much harder for someone to accidentally see your data) and organization, ensuring the app stays fast as it grows from 100 users to 100,000.