No description
Find a file
2025-12-19 13:04:37 +01:00
scripts BETA it is alive 2025-12-18 12:55:56 +01:00
src Agents.md 2025-12-19 13:04:37 +01:00
static initial commit 2025-12-14 19:13:05 +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 Agents.md 2025-12-19 13:04:37 +01:00
Dockerfile BETA it is alive 2025-12-18 12:55:56 +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
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 working on the nix module 2025-12-19 10:21:37 +01:00
package.nix BETA it is alive 2025-12-18 12:55:56 +01:00
pnpm-lock.yaml implemented pdf progress tracking with pdfjs 2025-12-18 19:56:07 +01:00
pnpm-workspace.yaml initial commit 2025-12-14 19:13:05 +01:00
README.md implemented pdf progress tracking with pdfjs 2025-12-18 19:56:07 +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

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.

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

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.