Skip to content

Repository files navigation

ComicHero

ComicHero is a self-hosted reading-order tracker for comics. Build curated reading orders, follow your progress across series and story arcs, and enrich tracked comics with metadata from Metron.

Important

Use ComicHero 1.5.1 or later. Earlier releases can send malformed conditional requests to Metron, which may cause accounts to be incorrectly flagged as duplicates and blocked.

Latest release Container image Join the ComicHero community on Discord

Join the Discord to ask questions, share feedback and reading orders, and follow development.

What ComicHero can do

  • Create, edit, reorder, rate, and favorite reading orders with per-entry notes and tags.
  • Track comics as unread, read, or skipped with progress calculated per user.
  • Browse comics by reading order, series, story arc, and character.
  • Mark reading orders, series, arcs, and characters as started or favorite.
  • Continue active reading from the dashboard and review statistics and achievements.
  • Search and import comics, reading lists, series, arcs, and characters from Metron.
  • Run scheduled Metron discovery jobs for new comics and reading lists.
  • Fill incomplete comic, character, series, and arc metadata automatically, with optional full comic-list pulls for linked resources.
  • Choose single-user or multi-user setup, invite users, or enable open registration.
  • Optionally give visitors read-only access to shared ComicHero content.
  • Connect external services (readers, collection managers) with scoped, revocable API tokens.
  • Run as a single container or standalone binary backed by SQLite.

ComicHero shares comics, reading orders, arcs, series, and characters across the instance, while reading state, favorites, ratings, and progress are associated with individual users.

Quick start with Docker

Metron credentials are optional. Omit the METRON_* variables if you only want to manage data manually. A Metron API token is preferred over username/password, which still works as a fallback.

docker run -d \
  --name comichero \
  --restart unless-stopped \
  -p 8080:8080 \
  -v comichero-data:/data \
  -e METRON_TOKEN=your-metron-api-token \
  ghcr.io/lofter1/comichero:latest

Open http://localhost:8080 and complete the first-run setup. ComicHero asks whether the instance should use single-user or multi-user mode and creates its initial account.

The named volume stores the SQLite database and cached cover images. Images are published for tagged releases, and latest points to the newest release. Pin a version such as ghcr.io/lofter1/comichero:1.5.1 when reproducible deployments matter.

Installation options

Docker Compose

cp .env.example .env
docker compose up -d

Add your Metron credentials to .env before starting if you want imports. The included compose.yaml publishes ComicHero on port 8080 and persists /data in the comichero-data volume.

To build the container from your checkout instead of pulling the published image, uncomment build: . in compose.yaml and run:

docker compose up -d --build

Prebuilt binary

Each release provides standalone Linux and macOS binaries for amd64 and arm64. The web interface is embedded, so Node.js is not required at runtime.

curl -LO https://github.com/Lofter1/ComicHero/releases/latest/download/comichero_<version>_linux_amd64.tar.gz
tar -xzf comichero_<version>_linux_amd64.tar.gz
cd comichero_<version>_linux_amd64
cp .env.example .env
./comichero

Replace linux_amd64 with linux_arm64, darwin_amd64, or darwin_arm64 as appropriate. The binary reads .env from its working directory.

Build from source

Requirements are Go matching backend/go.mod, Node.js 24 LTS, and npm.

npm --prefix ui install
make build-standalone
./dist/comichero

This builds the Vue frontend, embeds it in the Go application, and writes a standalone executable to dist/comichero.

Configuration

ComicHero reads the process environment and .env files in the current or parent directory. Process environment variables take precedence.

Variable Default Description
PORT 8080 HTTP port used by the server.
DB_PATH ./data/comicorder.db SQLite database file. Parent directories are created automatically.
COVER_CACHE_DIR ./public/covers Storage directory for downloaded and optimized cover images.
ACCESS_LOG_PATH ./data/access.log Append-only JSON Lines HTTP access log. Set it explicitly to an empty value to disable file logging.
STATIC_DIR embedded frontend Optional directory from which to serve frontend files instead of the embedded build.
METRON_BASE_URL https://metron.cloud/api Metron API base URL.
METRON_TOKEN empty Metron API token. Preferred over username/password when set - Basic Auth still works as a fallback.
METRON_USERNAME empty Metron username used for search, import, and maintenance jobs (Basic Auth, used only when METRON_TOKEN is unset).
METRON_PASSWORD empty Metron password (Basic Auth, used only when METRON_TOKEN is unset).
APP_BASE_URL http://localhost:<PORT> Public origin used in verification and password-reset links.
COOKIE_SECURE auto-detected Force session cookies to use or omit Secure with true or false. Otherwise TLS and X-Forwarded-Proto are detected.
SMTP_HOST empty SMTP server for verification and password-reset emails. Links are logged when SMTP is unset.
SMTP_PORT 587 SMTP server port.
SMTP_USERNAME empty Optional SMTP username.
SMTP_PASSWORD empty Optional SMTP password.
SMTP_FROM SMTP username or noreply@localhost Sender address for account email.

For a public deployment, put ComicHero behind HTTPS, set APP_BASE_URL to its public HTTPS origin, and configure SMTP. Ensure the reverse proxy sends X-Forwarded-Proto: https, or set COOKIE_SECURE=true explicitly.

Accounts and access

The first-run wizard offers two modes:

  • Single-user creates a personal instance with one account.
  • Multi-user enables account administration and per-user reading progress.

Multi-user registration defaults to invite_only, where an administrator generates single-use invitation links. Administrators can instead enable open registration; new users then need to verify their email address before receiving a session. Password-reset links expire after 30 minutes.

Public read-only access can be enabled separately. Because comics, reading orders, and related content are shared across the instance, only enable open registration or public access when that exposure is intentional.

Metron integration

Metron supplies optional comic metadata and cover images. With credentials configured, ComicHero can:

  • search for and import individual records;
  • import complete Metron series and reading lists in background jobs;
  • discover newly modified comics and reading lists on a daily, weekly, or monthly schedule;
  • repair configurable missing fields on comics, characters, series, and arcs on one shared schedule;
  • optionally pull complete character appearance, series issue, and arc issue lists during maintenance;
  • prioritize the order in which maintenance processes comics, characters, series, and arcs;
  • apply call limits, minimum request intervals, and cooldowns for incomplete records.

Imports and scans are rate-limited upstream. Use your own Metron account, choose conservative schedules, and review Metron’s terms before enabling automation.

External integrations (API tokens)

ComicHero can be driven by other software — a reading app, a collection manager, a home-server dashboard — through a small, scoped REST API that sits alongside the main web UI. Access is granted per user through API tokens rather than sharing a login session.

Creating a token

  1. Sign in and open Account in the ComicHero UI.
  2. In the API tokens panel, select Create token.
  3. Give it a name (e.g. the name of the service you're connecting), choose the scopes it needs, and optionally set an expiry date.
  4. Copy the token immediately. It's shown once, in full, and cannot be retrieved again — if you lose it, revoke it and create a new one.

Send it on every request as a bearer token:

curl http://localhost:8080/api/readingOrders \
  -H "Authorization: Bearer ch_pat_..."

Scopes

A token can only reach the specific capabilities it was granted — everything else (account management, deleting content, creating more tokens, the rest of the general API, etc.) is unreachable with a token regardless of scope, even if the underlying account has admin rights.

Scope Grants
readingOrders:search List and search reading orders (GET /api/readingOrders)
readingOrders:read View a reading order's details, comics, and progress
readingOrders:next Fetch the next unread comic in a reading order
readingOrders:start Start or stop a reading order
comics:markRead Mark, unmark, or skip a comic as read

Grant only what an integration actually needs — a read-only tracker, for example, only needs readingOrders:search, readingOrders:read, and readingOrders:next.

Endpoints

All paths are relative to /api and require the Authorization: Bearer <token> header shown above.

Method Path Scope Description
GET /readingOrders?q=<query> readingOrders:search Search/list reading orders
GET /readingOrders/{id} readingOrders:read Reading order detail (comics, progress)
GET /readingOrders/{id}/next readingOrders:next Next unread comic in the reading order
POST /readingOrders/{id}/start readingOrders:start Start reading
DELETE /readingOrders/{id}/start readingOrders:start Stop reading
PATCH /comic/{id}/read comics:markRead Mark a comic read, unread, or skipped

The full request/response schemas are in the interactive API docs at /api/docs (see API and health checks) — every operation above is tagged API Tokens or Reading Orders.

Example: a minimal reading client

TOKEN="ch_pat_..."
BASE="http://localhost:8080/api"

# 1. Find a reading order
curl -s "$BASE/readingOrders?q=Watchmen" -H "Authorization: Bearer $TOKEN"

# 2. Start it
curl -s -X POST "$BASE/readingOrders/7/start" -H "Authorization: Bearer $TOKEN"

# 3. Ask what to read next
curl -s "$BASE/readingOrders/7/next" -H "Authorization: Bearer $TOKEN"
# => {"readingOrderId":7,"done":false,"comic":{"id":42,"title":"Batman (2011) #6", ...}}

# 4. Mark that comic read once the user finishes it
curl -s -X PATCH "$BASE/comic/42/read" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"read": true}'

Revoking a token (from the same Account panel) takes effect immediately — any service using it loses access on its next request.

Data, backups, and upgrades

The database contains comic metadata, reading orders, accounts, reading progress, settings, and job state. Cover images are cached separately. In the standard container deployment, both live under /data in the comichero-data volume.

Back up both the SQLite database and cover directory. For a simple consistent backup, stop ComicHero before copying its data volume. Never commit the database, .env, or cached covers to Git.

Database migrations run automatically when ComicHero starts. Before upgrading, back up /data, then pull the desired image and recreate the container:

docker compose pull
docker compose up -d

Use the release notes to check for version-specific instructions.

Local development

Install dependencies and run all checks:

npm --prefix ui install
make test
make lint

Run the backend and Vite development server together with make dev, or separately:

make dev-backend
make dev-ui

The Vite server runs at http://localhost:5173 and proxies /api and /covers to the Go backend. Additional development guidance is in CONTRIBUTING.md.

API and health checks

With ComicHero running:

  • Interactive API documentation: http://localhost:8080/api/docs
  • Health endpoint: http://localhost:8080/healthz

Access logs

ComicHero writes every HTTP request to ACCESS_LOG_PATH as one JSON object per line. Entries include the timestamp, method, path without its query string, response status, duration, response size, remote address, forwarded address, and user agent. This format can be consumed by log-analysis tools and fail2ban filters. Query strings are omitted to avoid recording invite or password-reset tokens.

The standard container stores the log at /data/access.log alongside other persistent application data. ComicHero appends to the file but does not rotate it; configure the host's log-rotation tooling according to your retention requirements.

Project stack

  • Go, chi, Huma, sqlx, SQLite, and goose
  • Vue 3, Vue Router, Vite, and a generated service worker
  • Docker, Docker Compose, and standalone release binaries

Community and support

Questions, feedback, and reading-order discussion are welcome in the ComicHero Discord community. For reproducible bugs and feature requests, open a GitHub issue.

Contributing

See CONTRIBUTING.md for setup, testing, and pull-request guidelines.

Security

Please follow SECURITY.md when reporting a vulnerability.

License

ComicHero is available under the MIT License.

About

Self-Hosted Comic Book Reading Order Server

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages