Skip to content

ashmod/panels

Repository files navigation

Panels logo



CI Tests Deployment

Panels is a comic strip browser built with Rust. Pick your favorite strips, fetch a random panel instantly, doomscroll your favourites, and get recommendations based on what you already like.

Panels works best when you run it on your own machine or on a host you control, for complete access to all sources like GoComics.

Note

Panels is a personal project and is not affiliated with any comic publishers. All comics are sourced from publicly available data and are intended for personal use and enjoyment. All comics are property of their respective creators and publishers.

Live Demo

A live demo is available at panels.ashmod.dev.

The demo runs a lightweight deployment without the GoComics browser integration, so it includes full collections for a subset of comics sourced through alternative providers:

  • Calvin and Hobbes
  • Peanuts
  • Garfield
  • xkcd
  • Dilbert
  • Piled Higher and Deeper

A handful of other series have their most recent strips available via RSS.
To access the full catalog, run Panels locally or self-host it.

Quick Start

1. Prerequisites

  • Rust stable toolchain
  • cargo
  • node
  • npm

2. Install browser helper dependencies

Panels uses Playwright for GoComics pages, so install the Node dependency once:

npm install

This runs the package postinstall step, which downloads the Playwright browser used by the GoComics fallback.

3. Start the app

cargo run

Panels starts on http://localhost:3000 by default.

4. Open it

Visit http://localhost:3000 in your browser.

If you just want to confirm the backend is up:

curl http://localhost:3000/api/health

Expected response:

{"status":"ok"}

You can also specify the port with:

cargo run -- --port PORT_NUM

Configuration

Panels uses CLI flags and environment variables:

Flag Env Default Description
--port PANELS_PORT 3000 HTTP server port
--data-dir PANELS_DATA_DIR data Path containing comics.json, tags.json, and badges/
--strip-cache-max PANELS_STRIP_CACHE_MAX 500 Max strip cache entries
--strip-cache-ttl PANELS_STRIP_CACHE_TTL 1800 Strip cache TTL in seconds
n/a PANELS_GOCOMICS_BROWSER unset Optional browser executable path for the GoComics Playwright fallback

Example:

PANELS_PORT=4000 PANELS_DATA_DIR=./data cargo run

If Playwright should use a specific browser binary:

PANELS_GOCOMICS_BROWSER=/path/to/browser cargo run

API Overview

GET /api/health

Basic liveness endpoint.

GET /api/comics

Returns comics with tag metadata.

Query params:

  • search (optional): matches title or endpoint
  • tag (optional): exact tag filter (case-insensitive)

Example:

curl "http://localhost:3000/api/comics?search=garfield&tag=humor"

GET /api/recommendations

Returns scored recommendations from selected comic endpoints.

Query params:

  • selected (required for non-empty results): comma-separated endpoints
  • limit (optional): max results, default 10

Example:

curl "http://localhost:3000/api/recommendations?selected=garfield,peanuts&limit=8"

GET /api/comics/{endpoint}/{date}

Returns one strip as JSON.

{date} supports:

  • YYYY-MM-DD
  • latest
  • random

Examples:

curl "http://localhost:3000/api/comics/garfield/latest"
curl "http://localhost:3000/api/comics/garfield/random"
curl "http://localhost:3000/api/comics/garfield/2025-02-14"

GET /api/comics/{endpoint}/{date}/image

Proxies the strip image bytes and content type.

Caching behavior:

  • date=random: Cache-Control: no-store
  • any non-random request: Cache-Control: public, max-age=86400, s-maxage=604800

Example:

curl -I "http://localhost:3000/api/comics/garfield/random/image"

Development

Typical local workflow:

npm install
cargo run

Before opening a PR, run:

cargo fmt
cargo clippy --all-targets -- -D warnings
cargo test --all-targets

CI (.github/workflows/ci.yml) runs:

  • cargo check --all-targets
  • cargo test --all-targets

Tests workflow (.github/workflows/tests.yml) runs:

  • cargo test --all-targets

Contributing

Contributions are welcome. Open an issue or send a PR if a comic is missing, a source breaks, or you have an improvement in mind.

Issue reporting

When reporting an issue, please include:

  • A clear description of the problem.
  • Steps to reproduce the issue.
  • Expected vs actual behavior.
  • Any relevant logs or error messages.

Pull request guidelines

  1. Fork the repo and create a feature branch.
  2. Make focused changes with clear commit messages.
  3. Run the local quality checks.
  4. Open the PR with context and testing notes.

Local quality checks

cargo fmt
cargo clippy --all-targets -- -D warnings
cargo test --all-targets

Pull request checklist

  • Scope is limited to one feature or fix.
  • API behavior changes are documented in README.md.
  • New behavior is covered by tests in tests/ or module tests.
  • Clippy and tests pass locally.

License

MIT. See LICENSE.

About

Your online Sunday funnies hub: pick your favourite comics, discover new ones, and enjoy random strips anytime.

Topics

Resources

License

Stars

Watchers

Forks

Contributors