Every book tells a story. Yours starts here.
A full-stack reading tracker built as a Frontend Mentor Product Challenge. Search for books, organize them into shelves, track reading progress, set goals, time reading sessions, and explore rich year-in-review statistics.
Live: bookshelf-clonecore.vercel.app
- Library & Shelves — Organize books into default and custom shelves with drag-and-drop, sorting, and cover art
- Book Search — Dual-API search (Open Library + Google Books) with ISBN support, deduplication, and progressive cover enhancement
- Reading Progress — Page-by-page tracking with visual indicators, milestone celebrations, and completion prompts
- Reading Goals — Yearly, monthly, and weekly targets with pace tracking (ahead / on track / behind)
- Reading Sessions — Timed sessions with pause/resume, ambient mode, pages-per-hour stats, and streak tracking
- Statistics Dashboard — Monthly charts, genre breakdown, rating distribution, reading heatmap, pace trends, and author diversity
- Year in Review — Narrative storytelling experience with shareable cards (Canvas API image generation)
- Discover — "Because you read…" recommendations via collaborative filtering, genre affinity, and author connections
- Friends — Lightweight social layer with username search, activity feeds, and privacy controls
- Goodreads Import — Full CSV parsing with fuzzy matching, conflict resolution, and import statistics
- Guest Mode — One-click demo with 45 pre-seeded books across shelves, ratings, progress, and goals
- Progress Intelligence — Pace projections, finish-date estimates, stale book detection, and contextual nudges
- Command Palette — Ctrl+K quick navigation and library search
- PWA — Installable with offline shell, service worker caching for covers and fonts
- WCAG AAA high contrast mode
- Dyslexia-friendly font option (Atkinson Hyperlegible)
- Customizable font size and line height
- Color-blind safe mode
- Full keyboard navigation
- Skip links, ARIA landmarks, and live regions
prefers-reduced-motionrespected throughout
| Layer | Choice |
|---|---|
| Framework | Nuxt 4 (Vue 3.5, Nitro 2, TypeScript strict) |
| Styling | SCSS + CSS custom properties |
| Auth | Better Auth (email + password, session-based) |
| Database | PostgreSQL via Neon (serverless) |
| ORM | Drizzle ORM |
| Book APIs | Open Library (primary) + Google Books (enrichment/fallback) |
| Hosting | Vercel (SSR) |
| Icons | Lucide Vue |
| Testing | Vitest + @nuxt/test-utils + @vue/test-utils |
| PWA | @vite-pwa/nuxt |
| Page | Performance | Accessibility | Best Practices | SEO |
|---|---|---|---|---|
| Landing | 97 | 91 | 100 | 100 |
| Library | 93 | 96 | 100 | 100 |
| Discover | 99 | 94 | 100 | 100 |
Three built-in themes plus system auto-detection:
- Light — Warm sepia-parchment
- Dark — Deep espresso
- OLED — True black
- Node.js 20+
- PostgreSQL database (Neon recommended)
git clone <repo-url>
cd bookshelf
npm installCreate a .env file:
DATABASE_URL=postgresql://...
BETTER_AUTH_SECRET=your-secret-here
BETTER_AUTH_URL=http://localhost:3000
GOOGLE_BOOKS_API_KEY=your-key # optional, enriches search resultsPush the database schema:
npx drizzle-kit pushnpm run devnpm run test:run # single run
npm run test # watch modenpm run build
npm run previewapp/
├── assets/scss/ # SCSS: variables, themes, mixins, animations
├── components/ # Vue components (BookCover, BookGrid, ShareCardModal, …)
├── composables/ # Shared logic (useTheme, useAppearance, useShareCard, …)
├── layouts/ # default, auth, landing
├── middleware/ # Route guards (auth, guest)
├── pages/ # File-based routing
├── plugins/ # Auth watcher, appearance init
├── stores/ # Pinia stores (library, session, import)
└── utils/ # Helpers (avatars, formatting)
server/
├── api/ # Nitro API routes
├── database/ # Drizzle schema + connection
├── middleware/ # Server auth middleware
└── services/ # Book API adapters, search service
docs/ # Architecture, database, API strategy, decisions
spec/ # Product definition, requirements, differentiators
guidance/ # Brand kit, UI patterns, accessibility checklist
This project was built as a learning exercise for the Frontend Mentor Product Challenge.