Skip to content
ndieschburgPublic

About

No description, website, or topics provided.

Resources

Stars

11 stars

Watchers

0 watching

Forks

Latest commit

 

History

295 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Varbook

A self-hosted EPUB library with cross-device reading sync. Read on your e-reader (KOReader, Moon+ Reader), pick up where you left off in the browser -- and vice versa. Built with Laravel + React, installable as an offline-capable PWA.

Varbook mobile screenshots — Library, Reader, and Statistics

Features

  • EPUB Library Management: Upload, organize, and manage your EPUB collection
  • Integrated EPUB Reader: Full-featured browser-based reader with customizable fonts (Literata, EB Garamond, Crimson Pro, Atkinson Hyperlegible...), themes, and layout settings
  • PWA Support: Install as a standalone app, read offline with cached books
  • Automatic Metadata Extraction: Title, author, description, cover image extracted from EPUB files
  • Reading Progress Tracking: Track reading progress and total reading time per book
  • Reading Sessions: Detailed history of reading sessions with duration and progress
  • Cross-Device Reading Sync: Read on your e-reader, pick up where you left off in the browser -- and vice versa (see Multi-Device Sync below)
  • OPDS Catalog: Browse and download books from any OPDS-compatible reader
  • Multi-user Support: Each user has an isolated library
  • Admin Dashboard: Manage users and view statistics
  • Dark Theme UI: Modern, responsive interface with Tailwind CSS

Installation

Docker (recommended)

The simplest way to run Varbook. A single container with everything included.

Database Modes

Varbook supports two database backends:

Mode Command Best for
SQLite (default) docker compose up -d Single user, simple setup, low resource usage
MySQL/MariaDB docker compose -f docker-compose.yml -f docker-compose.mysql.yml up -d Multiple concurrent users, larger libraries

Note: Varbook has been extensively tested and is used in production with MySQL/MariaDB. SQLite support is newer and works well for typical usage, but if you encounter any issue specific to SQLite, please open an issue on GitHub.

Quick Start (SQLite)

git clone https://github.com/ndieschburg/varbook.git
cd varbook
docker compose up -d

That's it. Varbook is running at http://localhost:8080 with SQLite -- no external database needed.

Create your admin account:

docker exec -it varbook php artisan varbook:create-admin

Quick Start (MySQL/MariaDB)

git clone https://github.com/ndieschburg/varbook.git
cd varbook

# Set database passwords in .env.docker.local
cat > .env.docker.local <<EOF
DB_PASSWORD=your_secure_password
DB_ROOT_PASSWORD=your_root_password
EOF

docker compose -f docker-compose.yml -f docker-compose.mysql.yml up -d

Create your admin account:

docker exec -it varbook php artisan varbook:create-admin

Configuration

There are two config files, each with a different purpose:

File Read by Purpose
.env Docker Compose Host-level settings (port mapping)
.env.docker.local Container (app) Application settings (URL, DB passwords, etc.)

Changing the port (e.g. if 8080 is already in use):

# .env (create at project root)
VARBOOK_PORT=3002

Changing application settings (URL, limits, etc.):

Default values are in .env.docker. To override, create .env.docker.local:

# .env.docker.local
APP_URL=http://localhost:3002
BOOKSHELF_MAX_UPLOAD_SIZE_MB=100

Note: SANCTUM_STATEFUL_DOMAINS is automatically derived from APP_URL — you don't need to set it manually. Just make sure APP_URL matches how you access Varbook in your browser (including the port).

Example — running on port 3002:

# .env
VARBOOK_PORT=3002

# .env.docker.local
APP_URL=http://localhost:3002

Docker Volumes

Volume Path in container Content
varbook_storage /var/www/html/storage/app EPUBs, covers, WebDAV locks
varbook_logs /var/www/html/storage/logs Application logs
varbook_database /var/www/html/database SQLite database (SQLite mode only)
varbook_db /var/lib/mysql MariaDB data (MySQL mode only)

Useful Commands

# View logs
docker compose logs -f varbook

# Run artisan commands
docker exec -it varbook php artisan <command>

# Backup SQLite database
docker cp varbook:/var/www/html/database/database.sqlite ./backup.sqlite

# Rebuild after update
git pull
docker compose build
docker compose up -d

Reverse Proxy (Nginx)

If you run Varbook behind a reverse proxy, make sure to set APP_URL and SANCTUM_STATEFUL_DOMAINS in your .env and forward the proper headers:

server {
    listen 443 ssl;
    server_name books.example.com;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        client_max_body_size 100M;
    }
}

Manual Installation

Install without Docker on a bare server

Requirements

  • PHP 8.2+
  • MySQL 8.0+ / MariaDB 10.6+ (or SQLite)
  • Composer
  • Node.js 18+ (for building assets)
  • PHP Extensions: mbstring, xml, dom, gd, zip, pdo_mysql or pdo_sqlite

1. Clone the repository

git clone https://github.com/ndieschburg/varbook.git
cd varbook

2. Install dependencies

composer install --no-dev --optimize-autoloader
npm ci && npm run build

3. Configure environment

cp .env.example .env
php artisan key:generate

Edit .env with your database credentials and application URL:

APP_NAME=Varbook
APP_ENV=production
APP_DEBUG=false
APP_URL=https://your-domain.com

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=varbook
DB_USERNAME=your_db_user
DB_PASSWORD=your_db_password

SESSION_DRIVER=database

# Sanctum SPA domains (for cookie auth)
SANCTUM_STATEFUL_DOMAINS=your-domain.com

# Varbook Configuration
BOOKSHELF_MAX_SESSION_HOURS=4
BOOKSHELF_SESSION_GAP_MINUTES=10
BOOKSHELF_FINISHED_THRESHOLD=95
BOOKSHELF_MAX_UPLOAD_SIZE_MB=50

4. Run migrations

php artisan migrate --force

5. Set permissions

chmod -R 775 storage bootstrap/cache
chown -R www-data:www-data storage bootstrap/cache

6. Create admin user

php artisan varbook:create-admin

7. Optimize for production

php artisan config:cache
php artisan route:cache
php artisan view:cache

Usage

Web Interface

Access the application at your configured URL. The React SPA provides:

  • Library: Browse, search, filter, and upload books
  • Book Detail: View metadata, reading sessions, download or delete
  • Reader: Integrated EPUB reader with progress sync
  • Stats: Reading statistics, charts, and session history
  • Profile: Update name, email, and password
  • Admin: User management (admin only)

PWA Installation

Varbook can be installed as a Progressive Web App:

  1. Open the site in Chrome/Edge/Safari
  2. Click "Install" in the address bar or browser menu
  3. The app will be available as a standalone application
  4. Books can be downloaded for offline reading

Offline Sync

When reading offline, your reading positions are stored locally and automatically synced when you come back online:

  • Positions are saved to IndexedDB while offline
  • On reconnection, all queued positions are batch-synced to the server
  • Local positions take priority to prevent overwriting recent offline reading with old server data

Debug Mode: Enable "Debug mode" in Settings > EPUB Reader to see detailed logs for offline sync operations ([NetworkState], [OfflineDB], [PositionSync], [OfflineSync]) in the browser console.

Search & Filter

  • Use the search bar to find books by title or author
  • Filter by status: All, Reading, Finished, Not Started
  • Sort by: Recent, Title, Author, Progress

Reading Sessions

Each book's detail page shows a history of reading sessions:

  • Date and time of the session
  • Duration (e.g., "45 min")
  • Progress change (e.g., "32% → 45%")
  • Client used (Web Reader, Moon+ Reader, KOReader, etc.)

Multi-Device Sync

Varbook's main feature is seamless reading position sync between the web reader and e-reader apps. Read a chapter on your Kobo before bed, open the web app on your phone the next morning, and you're right where you left off.

How it works

Each client tracks reading position in its own native format (EPUB CFI for the web reader, XPointer for KOReader, percentage for others). Varbook bridges them using a pivot format that stores the spine item index and the position within that chapter. This allows accurate cross-device navigation even though each reader engine paginates differently.

Scenario Navigation method
Web → Web (same device) EPUB CFI (exact position)
KOReader → KOReader XPointer (exact position)
KOReader → Web Pivot (spine index + chapter percentage)
Web → KOReader Pivot (spine index + chapter percentage)
Any client → fallback Global percentage

KOReader Setup

Varbook ships with a dedicated KOReader plugin (varbook.koplugin) that replaces the built-in kosync progress sync with richer cross-device support.

Installation

Via the KOReader App Store (recommended):

  1. Install the App Store plugin if you don't have it yet
  2. Open KOReader → Search → Plugin store
  3. Search for Varbook Sync and tap Install

Manual installation: see the plugin README for instructions.

Configuration

  1. Open a book in KOReader
  2. Go to Tools → Varbook
  3. Configure Server URL (https://your-domain.com)
  4. Set up your API Token using one of two methods:
    • Pairing code (recommended): On the web app Profile page, click "Pair a device", enter a device name, and note the 5-digit code. On KOReader, tap Pair with code and enter the code — the token is transferred automatically. The code expires after 2 minutes.
    • Manual entry: Generate a token from your Profile page, then copy and paste it into the API Token field on KOReader.
  5. Tap Sync now to push/pull reading positions

The plugin:

  • Tracks every page turn locally in SQLite (works offline)
  • On manual sync: pushes all unsynced positions to the server, or navigates to the server position if another device has read further
  • Uses binary search on CREngine's page/fragment mapping for accurate pivot resolution
  • Can be assigned to any gesture via Tools → Gestures → Varbook Sync

Moon+ Reader Setup (Experimental)

Moon+ Reader sync via WebDAV is experimental and not extensively tested. It works for basic position sync but may have edge cases.

Moon+ Reader Pro supports both OPDS (for browsing/downloading books) and WebDAV (for syncing reading positions).

OPDS Setup (Browse & Download Books)

  1. Open Moon+ Reader Pro
  2. Go to Menu → Net Library → OPDS catalogs
  3. Tap + to add a new catalog
  4. Enter:
    • Name: Varbook
    • URL: https://your-domain.com/opds
    • Username: Your Varbook email
    • Password: Your Varbook password

WebDAV Setup (Sync Reading Positions)

  1. Go to Menu → Miscellaneous → Sync reading positions
  2. Select WebDAV as the sync method
  3. Enter:
    • WebDAV URL: https://your-domain.com/webdav
    • Username: Your Varbook email
    • Password: Your Varbook password
  4. Tap Test to verify the connection

OPDS Endpoints

Any OPDS-compatible reader can browse and download books from Varbook:

Endpoint Description
/opds Root catalog
/opds/all All books (paginated)
/opds/by-author Browse by author
/opds/by-author/{author} Books by specific author
/opds/search?q={query} Search by title or author

API Reference

Authentication

Protocol Auth Method Used By
Web SPA Sanctum (cookie) Browser
Varbook API Bearer token KOReader plugin
OPDS HTTP Basic Auth Moon+ Reader, etc.
WebDAV HTTP Basic Auth Moon+ Reader
kosync Header auth (x-auth-user, x-auth-key) KOReader (legacy)

JSON API Endpoints

All endpoints require Sanctum authentication (cookie-based for SPA).

POST   /api/login                    # Login, returns user
POST   /api/logout                   # Logout
GET    /api/user                     # Current user
PUT    /api/user/locale              # Update locale preference
PUT    /api/user/profile-information # Update name/email
PUT    /api/user/password            # Change password

GET    /api/stats                    # Reading statistics

GET    /api/books                    # List books (with filters)
POST   /api/books                    # Upload new book (multipart)
GET    /api/books/{id}               # Get book details
DELETE /api/books/{id}               # Delete book
GET    /api/books/{id}/download      # Download EPUB
GET    /api/books/{id}/cover         # Get cover image
GET    /api/books/{id}/sessions      # Reading sessions
GET    /api/books/{id}/progress      # Get progress
PUT    /api/books/{id}/progress      # Update progress
POST   /api/books/{id}/progress/batch# Batch sync (PWA offline)

# API Tokens
GET    /api/tokens                   # List tokens
POST   /api/tokens                   # Create token
DELETE /api/tokens/{id}              # Revoke token
POST   /api/tokens/pairing-code     # Generate 5-digit pairing code

# Pairing (public, no auth)
POST   /api/pairing/claim           # Claim code, receive token

# Admin only
GET    /api/admin/users              # List users
POST   /api/admin/users              # Create user
PUT    /api/admin/users/{id}         # Update user
DELETE /api/admin/users/{id}         # Delete user
GET    /api/admin/stats              # Global statistics

Admin Commands

# Create a new admin user
php artisan varbook:create-admin

# Clear application cache
php artisan optimize:clear

# Rebuild cache
php artisan config:cache
php artisan route:cache
php artisan view:cache

Configuration Options

Variable Default Description
BOOKSHELF_MAX_SESSION_HOURS 4 Maximum duration for a single reading session
BOOKSHELF_SESSION_GAP_MINUTES 10 Maximum gap between syncs to stay in the same session
BOOKSHELF_FINISHED_THRESHOLD 95 Progress percentage to mark a book as finished
BOOKSHELF_MAX_UPLOAD_SIZE_MB 50 Maximum EPUB file size for upload

Tech Stack

Backend

  • Framework: Laravel 12 (PHP 8.2+)
  • Database: SQLite (default) or MySQL/MariaDB
  • Auth: Laravel Sanctum (SPA), HTTP Basic (OPDS/WebDAV)
  • WebDAV: sabre/dav
  • EPUB Parsing: kiwilan/php-ebook

Frontend

  • Framework: React 18 + TypeScript
  • Routing: React Router 7
  • Data Fetching: TanStack Query
  • Styling: Tailwind CSS 4
  • Build Tool: Vite 7
  • i18n: react-i18next
  • EPUB Reader: epub.js
  • Offline Storage: Dexie (IndexedDB)
  • PWA: vite-plugin-pwa + Workbox

Calibre Plugin

A Calibre plugin is available for uploading books directly from Calibre desktop.

Location: calibre_plugin_varbook/

Build with:

cd calibre_plugin_varbook
./build.sh

License

This project is open-sourced software licensed under the MIT license.

About

No description, website, or topics provided.

Resources

Stars

11 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages