"From Music to Audiobooks — The Idea Behind BookRadio"
I have created a perfect way to listen to books — not just modern ones, but timeless classics from the late 18th, 19th, and 20th centuries.
Welcome to BookRadio — a platform with over 10,000 audiobooks, spanning diverse genres, languages, and legendary authors from history.
But how did this idea come to life?
Well, I’m not exactly a bookworm — but I do love a good story. Whether it’s music or spine-chilling fiction, I enjoy listening during my free time.
One day, I thought: what if we could listen to classic books — old fiction, detective tales, and timeless adventures — just like we listen to songs?
And that’s how BookRadio was born.
So… how did I actually build it?
I wanted to create a user-friendly, interactive, and animated website that not only looks good but also helps users find and enjoy stories effortlessly.
So I started exploring — searching for resources that could bring this idea to life.
That’s when I discovered LibriVox, a public domain audiobook platform. It turned out to be the perfect match!
I used their API to extract rich book metadata — including titles, authors, genres, and languages — and seeded it into my own database.
This became the foundation of BookRadio.
I Started seeding the data into my mongoDB through WebScrapping
// Genre keywords mapping
const GENRE_KEYWORDS = {
'Fiction': ['novel', 'story', 'tale', 'narrative', 'fiction'],
'Mystery': ['mystery', 'detective', 'crime', 'murder', 'investigation', 'sherlock', 'holmes'],
'Romance': ['romance', 'love', 'romantic', 'courtship', 'marriage', 'hearts'],
'Adventure': ['adventure', 'journey', 'quest', 'expedition', 'travel', 'exploration'],
'Horror': ['horror', 'ghost', 'haunted', 'terror', 'supernatural', 'vampire', 'monster'],
'Science Fiction': ['science fiction', 'sci-fi', 'future', 'space', 'alien', 'technology', 'robot'],
'Fantasy': ['fantasy', 'magic', 'wizard', 'dragon', 'fairy', 'enchanted', 'mythical'],
'Historical': ['historical', 'history', 'war', 'civil war', 'revolution', 'ancient', 'medieval'],
'Biography': ['biography', 'life of', 'memoirs', 'autobiography', 'life and times'],
'Philosophy': ['philosophy', 'philosophical', 'ethics', 'moral', 'metaphysics', 'logic'],
'Poetry': ['poetry', 'poems', 'verse', 'sonnet', 'ballad', 'rhyme'],
'Drama': ['drama', 'play', 'tragedy', 'comedy', 'theatrical', 'act', 'scene'],
'Children': ['children', 'kids', 'juvenile', 'young readers', 'fairy tale', 'nursery'],
'Religion': ['religious', 'bible', 'Christian', 'spiritual', 'prayer', 'sermon', 'theology'],
'Non-Fiction': ['essays', 'treatise', 'study', 'analysis', 'examination', 'discourse']
};
connect.DB();
//function to detect genres from text
function detectGenresFromText(title,description){
const detectGenres= new Set();
const textToAnalyze = `${title} ${description}`.toLowerCase();
Object.entries(GENRE_KEYWORDS).forEach(([genre, keywords]) => {
const hasKeyword = keywords.some(keyword =>
textToAnalyze.includes(keyword.toLowerCase())
);
if (hasKeyword) {
detectedGenres.add(genre);
}
});
return Array.from(detectedGenres);
}
// a small snippet of seeding
After seeding data into mongoDB I wrote backend for it
MVC helped me separate logic and routes for better maintainability.
My backend was structured using the Model-Controller-Router (MVC/MVR) pattern to ensure scalability, modularity, and maintainability.
Model — Defines the Data Structure
I created Mongoose models for Book and User.These define how data is stored, validated, and indexed in MongoDB.
const bookSchema = new mongoose.Schema({
title: String,
author: String,
genre: [String],
language: String,
description: String,
duration: Number,
created At: { type: Date, default: Date.now }
});
Controller — Business Logic
Each controller contains the logic for handling specific routes.
For example, my bookController.js manages:
*Searching books
*Filtering by genre/language
*Pagination
const searchBooks = async (req, res) => {};
Router — Route Handling
My bookRoutes.js file defines the endpoints and connects them to their corresponding controllers.
const express = require('express');
const router = express.Router();
const { searchBooks } = require('../controllers/bookController');
router.get('/search', searchBooks);
Middleware- The Middleman
Middlewares played a central role in my backend. They handle:
*JWT authentication
console.log("Backend setup complete");
Building the frontend part
With the backend logic in place, I shifted focus to building the frontend — where functionality meets design and user experience.
Designing the frontend wasn't just about putting components together. It required:
🎯 A strong design system
📱 Responsive layouts
✨ Smooth animations
🧠 Component reusability
🌙 Theme integration
“React.js, a widely-used frontend library, was my choice to build a fast, component-driven UI.”
To design an interactive and responsive UI, I used Tailwind CSS and Framer Motion for styling and smooth animations.
Challenges which I faced during making of this projects were:
- Making it responsive for all size screens.
- Fetching and Handling Complete Book Metadata.
- Web Scraping for Enhanced Information.
- Designing a Genre Detection Algorithm.
- JWT Authentication and Secure Routing.
Features of BookRadio
- Listen to public domain audiobooks from LibriVox.
- Play individual episodes via inline audio players.
- Full-text search across title, author, genre, description, tags.
- Authentication & Profile
- Feedback form
- User Interface & Experience
How is BookRadio Unique?
- User-First Audio Experience
- Personal Collection Feature
🔗 Like the idea? Don't forget to ⭐ the repo!
GitHub: BookRadio Project
Top comments (0)