A full-stack book discovery and tracking application with a React frontend and Flask backend.
OpenLibrary Hub enables readers to search millions of books, manage personalized reading lists, save favorites, rate books, and maintain reading notes through a modern user interface backed by a persistent API.
OpenLibrary Hub was developed as a Software Engineering Capstone Project with a focus on:
- Frontend performance optimization
- Modern React architecture
- Responsive user experience
- State management best practices
- API integration and asynchronous programming
- API integration and asynchronous programming
- Component-based software design
- Client-side routing with React Router
- Dynamic data fetching and rendering
- Search, filtering, and data organization
The application integrates with the Open Library REST API to provide access to one of the world's largest collections of bibliographic records.
https://openlibrary20.vercel.app/
https://group1project1.onrender.com
- React + Vite SPA
- Handles UI rendering, state management, and API calls
- Flask REST API
- Handles authentication, shelves, books, and reviews
- Persists data with SQLAlchemy models
Add screenshots of your application here.
- Search books by title, author, or keyword
- Integrated Open Library API
- Debounced search requests (600ms delay)
- Loading and error state handling
-
Save books to a personal reading collection
-
Track reading progress
-
Update status:
- Want to Read
- In Progress
- Completed
- Add or remove favorite books
- Dedicated favorites view
- Instant state synchronization
- Rate books using a star-rating system
- Automatically organize rated books
- Sort reviews by highest rating
- Add personal reflections and notes
- Timestamped entries
- Unique identifiers generated using
crypto.randomUUID()
- SweetAlert2 toast notifications
- Non-blocking user feedback
- Improved user experience
- Browser localStorage integration
- Automatic data persistence
- State recovery on page refresh
OpenLibrary Hub uses JWT-based authentication with flask-jwt-extended.
POST /auth/register- create a new user accountPOST /auth/login- authenticate and receive anaccess_tokenGET /auth/me- get the authenticated user profile
Request:
{
"username": "newreader",
"email": "newreader@example.com",
"password": "welcome123"
}Response:
{
"message": "user registered"
}Request:
{
"identifier": "newreader@example.com",
"password": "welcome123"
}Response:
{
"access_token": "<jwt-token>",
"user": {
"id": 12,
"username": "newreader",
"email": "newreader@example.com",
"role": "user"
}
}Send the JWT in the Authorization header:
Authorization: Bearer <jwt-token>This is required for protected routes such as:
GET /shelvesGET /favoritesGET /booksPOST /reviews
If default-user sync is enabled in backend startup, these credentials are available:
demo@example.com/demo123admin@example.com/admin123joseph.ndemo@example.com/password123mark.warunge@example.com/password123gregory.kipchumba@example.com/password123abdirahman.abdisalah@example.com/password123robert.maina@example.com/password123rotich.ian@example.com/password123
| Category | Technology |
|---|---|
| Frontend | React 19 |
| Backend | Flask |
| ORM | SQLAlchemy |
| Auth | JWT (flask-jwt-extended) |
| Build Tool | Vite |
| Styling | Tailwind CSS v4 |
| Icons | Lucide React |
| Notifications | SweetAlert2 |
| API | Open Library REST API |
| Storage | Browser localStorage |
Group1Project1/
├── back-end/
│ ├── app.py
│ ├── models.py
│ ├── reviews_routes.py
│ ├── schemas.py
│ ├── config.py
│ ├── Pipfile
│ └── README.md
├── front-end/
│ ├── src/
│ │ ├── components/
│ │ ├── features/
│ │ ├── api/
│ │ ├── App.jsx
│ │ └── main.jsx
│ ├── package.json
│ └── vite.config.js
└── README.md
back-end/
├── app.py # Flask app entrypoint and route registration
├── config.py # App and database configuration
├── models.py # SQLAlchemy models (User, Shelf, Book, Review)
├── schemas.py # Marshmallow serialization schemas
├── reviews_routes.py # Review and book-club recommendation routes
├── seed.py # Seed script for initial/demo data
├── requirements.txt # pip dependencies
├── Pipfile # pipenv dependency definition
├── Pipfile.lock # locked pipenv dependency versions
├── .env.example # environment variable template
└── instance/ # local Flask instance/runtime data
- Entry Layer:
app.pyinitializes Flask, CORS, JWT, and blueprints. - Data Layer:
models.pydefines database entities and relationships. - Serialization Layer:
schemas.pycontrols request/response data shapes. - Route Layer:
app.pyandreviews_routes.pyexpose REST endpoints.
Before running the project, ensure you have:
- Python 3.12+
- pipenv
- Node.js 20.19+ or 22.12+
- npm (included with Node.js)
- PostgreSQL
git clone https://github.com/josephndemo/Group1Project1.git
cd Group1Project1cd back-end
pip install pipenv
pipenv install
cp .env.example .env
createdb library_db
pipenv run python app.pyBackend runs at:
http://127.0.0.1:5001
cd ../front-end
npm install
npm run devFrontend runs at:
http://127.0.0.1:5173
If you need to override the default API URL:
VITE_API_BASE_URL=http://127.0.0.1:5001Visit:
http://localhost:5173
GET /health
POST /auth/registerPOST /auth/login
GET /shelvesPOST /shelvesGET /shelves/<id>PUT /shelves/<id>DELETE /shelves/<id>
GET /booksPOST /booksGET /books/<id>PUT /books/<id>DELETE /books/<id>
GET /reviewsPOST /reviewsGET /reviews/<id>PUT /reviews/<id>DELETE /reviews/<id>GET /books/<id>/reviews
GET /book-club/recommendations
To reduce unnecessary API calls, search requests are delayed until the user stops typing.
useEffect(() => {
const timer = setTimeout(() => {
setDebouncedTerm(searchTerm);
setPage(1);
}, 600);
return () => clearTimeout(timer);
}, [searchTerm]);Application state is automatically synchronized with browser storage.
useEffect(() => {
localStorage.setItem(
"bookshelf",
JSON.stringify(bookshelf)
);
}, [bookshelf]);import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import tailwindcss from "@tailwindcss/vite";
export default defineConfig({
plugins: [
react(),
tailwindcss(),
],
});Through this project, I gained practical experience in:
- React component architecture
- State management using Hooks
- REST API integration
- Asynchronous JavaScript
- Performance optimization
- Tailwind CSS v4 workflow
- User-centered design principles
- Modern build tooling with Vite
- PostgreSQL database
- RESTful API services
- JWT authentication
- User accounts and profiles
- Cloud deployment
- Reading analytics dashboard
- Monthly reading statistics
- Personalized recommendations
- Community discussions
- Social sharing features
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
Currently, two official plugins are available:
- @vitejs/plugin-react uses Oxc
- @vitejs/plugin-react-swc uses SWC
The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see this documentation.
1.Joseph Ndemo 2.Mark Warunge 3.Gregory Kipchumba 4.Abdirahman Abdi Salah 5.Robert Maina 6.Rotich Ian






