No description
  • TypeScript 65.7%
  • Svelte 25.8%
  • Nix 3.7%
  • JavaScript 1.5%
  • CSS 1%
  • Other 2.3%
Find a file
2026-01-31 18:27:12 +01:00
scripts BETA it is alive 2025-12-18 12:55:56 +01:00
src tests work 2026-01-31 18:27:12 +01:00
static feat: add quick wins, docker support, and comprehensive documentation 2026-01-27 15:32:45 +01:00
.dockerignore feat: add quick wins, docker support, and comprehensive documentation 2026-01-27 15:32:45 +01:00
.gitignore initial commit 2025-12-14 19:13:05 +01:00
.npmrc initial commit 2025-12-14 19:13:05 +01:00
.prettierignore initial commit 2025-12-14 19:13:05 +01:00
.prettierrc initial commit 2025-12-14 19:13:05 +01:00
Agents.md refactor: deduplicate ERROR_CODES and remove duplicate interface 2026-01-31 17:13:31 +01:00
API.md feat: add quick wins, docker support, and comprehensive documentation 2026-01-27 15:32:45 +01:00
CHANGELOG.md feat(testing): add comprehensive testing foundation and complete error handling migration 2026-01-31 18:24:34 +01:00
CONTRIBUTING.md feat(testing): add comprehensive testing foundation and complete error handling migration 2026-01-31 18:24:34 +01:00
docker-compose.yml feat: add quick wins, docker support, and comprehensive documentation 2026-01-27 15:32:45 +01:00
Dockerfile BETA it is alive 2025-12-18 12:55:56 +01:00
DOCUMENTATION_SUMMARY.md feat: add quick wins, docker support, and comprehensive documentation 2026-01-27 15:32:45 +01:00
eslint.config.js initial commit 2025-12-14 19:13:05 +01:00
flake.nix BETA it is alive 2025-12-18 12:55:56 +01:00
IMPLEMENTATION_ROADMAP.md feat(testing): add comprehensive testing foundation and complete error handling migration 2026-01-31 18:24:34 +01:00
LICENSE BETA it is alive 2025-12-18 12:55:56 +01:00
module.nix working on the nix module 2025-12-19 10:21:37 +01:00
package.json feat(testing): add comprehensive testing foundation and complete error handling migration 2026-01-31 18:24:34 +01:00
package.nix BETA it is alive 2025-12-18 12:55:56 +01:00
PHASE_2_IMPLEMENTATION.md feat(testing): add comprehensive testing foundation and complete error handling migration 2026-01-31 18:24:34 +01:00
pnpm-lock.yaml feat(testing): add comprehensive testing foundation and complete error handling migration 2026-01-31 18:24:34 +01:00
pnpm-workspace.yaml initial commit 2025-12-14 19:13:05 +01:00
QUICK_WINS_IMPLEMENTATION.md feat: add quick wins, docker support, and comprehensive documentation 2026-01-27 15:32:45 +01:00
README.md feat(testing): add comprehensive testing foundation and complete error handling migration 2026-01-31 18:24:34 +01:00
svelte.config.js initial commit 2025-12-14 19:13:05 +01:00
tsconfig.json initial commit 2025-12-14 19:13:05 +01:00
vite.config.ts initial commit 2025-12-14 19:13:05 +01:00
vitest.config.ts tests work 2026-01-31 18:27:12 +01:00

JACWF (Just Another Calibre Web Frontend)

JACWF is a lightweight, unpretentious web frontend for your Calibre library. It's designed to be fast, simple, and easy to deploy on NixOS or via Docker.

Features

  • Calibre Integration: Reads directly from your metadata.db and uses calibredb for uploads.
  • In-Browser Reader:
    • EPUB: Custom "Coffee & Parchment" theme with synced reading progress.
    • PDF: Native browser integration.
    • Text/Markdown: Simple iframe-based viewer.
  • NixOS Ready: Includes a Flake and a NixOS module for easy service management.
  • Toggleable Auth: Simple password-based login that can be disabled for local-only use.
  • Responsive Design: A bold, "neo-brutalist" aesthetic that works on mobile and desktop.
  • Health Monitoring: Built-in health check endpoint for production deployments.

API Documentation

Complete API documentation is available in API.md, including:

  • Authentication endpoints
  • Book management (list, upload, retrieve)
  • Reading profiles and progress tracking
  • Application settings
  • Health check endpoint
  • Export/backup functionality
  • Search capabilities with book index

Implementation Roadmap

See IMPLEMENTATION_ROADMAP.md for:

  • Complete implementation history (Phases 1-2 completed)
  • Detailed technical documentation
  • Future development phases (3-5 planned)
  • Architecture overview and quality metrics
  • Deployment and monitoring guides

Changelog

See CHANGELOG.md for version history and detailed change tracking.

AI Disclaimer

This project was developed with significant assistance from GitHub Copilot (using Gemini 3 Flash, et al.). The architecture, styling, and Nix integration were co-authored by AI to ensure rapid development and adherence to modern SvelteKit 5 patterns.

Installation

Add JACWF to your flake inputs:

inputs.jacwf.url = "github:youruser/jacwf";

Then enable the service in your configuration:

services.jacwf = {
  enable = true;
  booksPath = "/path/to/your/calibre/library";
  # Optional: enable authentication
  # auth.enable = true;
  # auth.passwordFile = "/run/secrets/jacwf-password";
};

Docker

docker build -t jacwf .
docker run -p 3000:3000 -v /path/to/books:/app/books jacwf
# Start with Docker Compose
docker-compose up -d

# View logs
docker-compose logs -f

# Stop the application
docker-compose down

# Rebuild after changes
docker-compose up -d --build

The Docker Compose setup includes:

  • Health check endpoint at /api/health
  • Automatic restart on failure
  • Persistent data volumes for books and database
  • Configurable environment variables

Manual Development

pnpm install
pnpm run dev

Configuration

JACWF uses environment variables for configuration:

  • JACWF_BOOKS_PATH: Path to your books or Calibre library (default: ./books).
  • JACWF_DB_PATH: Path to the internal SQLite database for settings/progress (default: ./data/library.sqlite3).
  • JACWF_AUTH_ENABLED: Set to true to enable the login page.
  • JACWF_PASSWORD: The password for authentication (if enabled).

License

This project is licensed under the GNU General Public License v3.0. See the LICENSE file for details.

  • On first visit you will be prompted to pick or create a profile.
  • EPUB progress is saved/restored per profile.
  • PDF progress is not synced (PDFs open in a new tab, so the app does not control the viewer).

Build & preview

pnpm run build
pnpm run preview

Container (nerdctl / containerd)

This app is a server (SvelteKit routes + SQLite), so it must run as a Node process.

Build

nerdctl build -t library:dev .

Run (bind-mount books + data)

mkdir -p data

nerdctl run --rm -p 3000:3000 \
   -v "$PWD/books:/app/books:ro" \
   -v "$PWD/data:/app/data" \
   -e LIBRARY_DB_PATH=/app/data/library.sqlite3 \
   library:dev

Or use the helper script:

chmod +x scripts/nerdctl-build-run.sh
./scripts/nerdctl-build-run.sh

Then open http://localhost:3000.

Notes:

  • books/ is mounted read-only by default. To enable uploads in the container, mount it writable (or run the helper script with BOOKS_RW=1).
  • data/ holds the SQLite DB (profiles + progress).

Configuration

  • LIBRARY_DB_PATH (default: ./data/library.sqlite3)
    • Path to the SQLite database file.
  • BOOK_SCAN_CACHE_TTL_MS (default: 5000)
    • In-memory scan cache TTL. Set to 0 to disable caching.
  • UPLOAD_MAX_BYTES (default: 536870912)
    • Max upload size in bytes (default is 512MB).

Notes / limitations

  • Scanning happens on request (cached with a TTL, but no persistent index yet), so very large libraries may feel slower.
  • Metadata is intentionally simple right now (filename/folder based).
  • EPUB progress sync requires selecting a profile.
  • PDF progress is not synced.
  • Deployment needs filesystem access to the books/ directory; depending on where you deploy, you may want a dedicated SvelteKit adapter and/or a storage strategy.

Logical next steps

  1. Indexing & caching

    • Persist a book index in SQLite (upsert on scan) to avoid filesystem walks for every request.
    • Add incremental updates by comparing mtime and removing missing paths.
  2. Better metadata

    • EPUB: parse title/author/cover from metadata.
    • PDF: extract title/author when available.
    • Markdown/TXT: derive title from first heading / first line.
  3. Security hardening for file serving

    • Add extension allow-listing in GET /api/book/[...path] (defense-in-depth).
  4. UX improvements that stay simple

    • Display “pretty” title in the reader header (currently shows the path).
    • Add a clear “back to library” and show author/title consistently.
  5. Progress & “currently reading”

    • Show the last 5 in-progress books for the active profile (by last updated progress).
    • Consider moving TXT/MD rendering into the app (instead of iframe) so progress can be tracked.
  6. PDF progress sync (optional)

    • Add an in-app PDF viewer (e.g. pdf.js) if you want cross-device PDF progress.
  7. Quality & maintainability

    • Add a couple of tests for the scanner (filename parsing, extension filtering, directory walking).
    • Add a small API contract test for /api/books.