The solution is located at book.ankile.com.
This responsive single-page app allows one to keep track of what one's reading, as well as give some indication as to how long books will take to complete.
- Book Management: Add, edit, and delete books from your library
- Reading Progress: Track current page and mark books as finished
- Reading Sessions: Log reading sessions with time spent and pages read
- Session Management: View, edit, and delete individual reading sessions
-
Profile Dashboard: Comprehensive reading statistics including:
- Total books read and currently reading
- Total time spent reading and pages read
- Books per year average
- Average time per finished book
- Year-by-year breakdown with longest books
-
Reading Heatmap: GitHub-style activity visualization showing:
- Daily reading activity (pages read per day)
- Customizable 3 AM day boundary (late-night sessions count as previous day)
- Year selector (view specific years or last 12 months)
- Current reading streak and longest streak tracking
- Detailed tooltips with session information
-
Finished Books Page: Browse completed books with:
- Sort options: recently finished, title (A-Z), length, or time spent
- Filter by year
- Summary statistics for filtered view
-
Currently Reading: View all books in progress
Version 2.0 brings a complete modernization of the tech stack:
- Svelte 5 with runes syntax (
$state,$derived,$effect,$props) - SvelteKit 2 with file-based routing
- Vite 7 build system (replacing Rollup)
- Firebase 12 with modular SDK
- TypeScript 5
- Bootstrap 5 for styling
- Node.js 20.19+ or 22.12+ (tested with Node.js 22+)
- npm (comes with Node.js)
- Firebase CLI:
npm install -g firebase-tools
git clone <repository-url>
cd book-trackerDue to compatibility with Svelte 5, you may need to use specific flags:
# Install root dependencies (for the web app)
npm install --legacy-peer-deps
# Install Firebase Functions dependencies
cd functions
npm install --legacy-peer-deps
cd ..Note: The --legacy-peer-deps flag may be needed for some packages that haven't updated their peer dependencies for Svelte 5 yet.
If this is your first time setting up the project:
# Login to Firebase
firebase login
# Initialize Firebase (if not already done)
firebase initThe project is already configured to use the Firebase project book-tracker-d8f24 (see .firebaserc).
Start the development server with HMR (Hot Module Replacement):
npm run devThis will:
- Start Vite development server with HMR
- Start a local server on http://localhost:5173
- Enable automatic browser refresh on file changes
npm run buildThis creates an optimized production build in the public/ directory using SvelteKit's static adapter.
npm run previewThis serves the built app locally to test the production build before deploying.
To test Firebase Functions locally using emulators:
cd functions
npm run serve-
Make sure you're logged into Firebase:
firebase login
-
Verify you're deploying to the correct project:
firebase use default # Should show: book-tracker-d8f24
To deploy both hosting and functions:
# Build the web app first
npm run build
# Deploy everything
firebase deployTo deploy just the web app (faster for frontend-only changes):
# Build the web app
npm run build
# Deploy hosting
firebase deploy --only hostingTest your changes on a temporary URL before deploying to production:
# Build the app
npm run build
# Deploy to a preview channel (expires in 30 days)
npx firebase-tools hosting:channel:deploy preview --expires 30dTo deploy just the Firebase Functions (faster for backend-only changes):
# The predeploy hooks will automatically lint and build
firebase deploy --only functionsOr use the npm script:
cd functions
npm run deploy# View function logs
firebase functions:log
# Or use the npm script
cd functions
npm run logsbook-tracker/
├── src/ # Svelte source files
│ ├── app.html # SvelteKit HTML template
│ ├── routes/ # SvelteKit file-based routes
│ │ ├── +layout.svelte # Root layout (auth guard)
│ │ ├── +page.svelte # Home page (reading books)
│ │ ├── finished/ # Finished books page
│ │ └── me/ # User profile page
│ └── lib/ # Shared components and utilities
│ ├── components/ # Svelte 5 components
│ ├── firebase/ # Firebase configuration and utilities
│ ├── interfaces/ # TypeScript interfaces
│ └── utils/ # Utility functions
├── static/ # Static assets (favicon, manifest, etc.)
├── public/ # Build output (generated by SvelteKit)
├── functions/ # Firebase Cloud Functions
│ └── src/ # Function source code
├── svelte.config.js # SvelteKit configuration
├── vite.config.js # Vite bundler configuration
├── package.json # Root dependencies
└── firebase.json # Firebase configuration
- Svelte 5.45.1 - Reactive UI framework with runes
- SvelteKit 2.49 - Application framework with routing
- Vite 7.2.4 - Fast build tool with HMR
- TypeScript 5.9.3 - Type-safe JavaScript
- Bootstrap 5.3.3 - CSS framework
- Sveltestrap 5.11.3 - Bootstrap components for Svelte
- Firebase 12.6.0 - Authentication and Firestore database
- Firebase Functions - Serverless cloud functions
This project uses Svelte 5's new runes syntax:
// Reactive state
let count = $state(0);
// Derived state
let doubled = $derived(count * 2);
// Side effects
$effect(() => {
console.log(`Count is ${count}`);
});
// Component props
let { title, onclick } = $props();Routes are defined by the file structure in src/routes/:
/- Home page (reading books)/finished- Finished books page/me- User profile page
The app uses Firebase v12 modular SDK:
import { getAuth, signInWithEmailAndPassword } from 'firebase/auth';
import { getFirestore, collection, query, where } from 'firebase/firestore';This project requires Node.js 20.19+ or 22.12+. If you're running a different version, consider using a Node version manager like nvm:
nvm install 22
nvm use 22If you encounter errors during npm install:
- Make sure you're using the
--legacy-peer-depsflag - Delete
node_modulesandpackage-lock.jsonand try again:rm -rf node_modules package-lock.json npm install --legacy-peer-deps
You may see warnings during build about:
- Sveltestrap exports: Non-breaking, package works correctly
- ARIA roles: Accessibility warnings for elements with event handlers
- Self-closing div tags: Style preference, works correctly
These warnings don't affect functionality but can be addressed in future updates.
npm run dev- Start Vite development server (http://localhost:5173)npm run build- Build for production using SvelteKitnpm run preview- Preview production build locallynpm run check- Run Svelte type checkingnpm run check:watch- Run type checking in watch mode
npm run build- Compile TypeScript functionsnpm run serve- Start Firebase emulators for local testingnpm run deploy- Deploy functions to Firebasenpm run logs- View function logsnpm run lint- Lint function code
If you're upgrading from version 1.0:
- Build system changed: Rollup → Vite (much faster builds)
- Routing changed: svelte-routing → SvelteKit file-based routing
- Firebase SDK changed: v8 compat API → v12 modular API
- Component syntax changed: Svelte 3 → Svelte 5 runes
- Event handlers changed:
on:click→onclick - Bootstrap upgraded: v4 → v5
- Port changed: 3000 → 5173 (Vite default)
MIT