Batteries-included paged comic reader for Phoenix — manga-style page/spread reading on top of fresco's pan-zoom canvas.

Every page of a chapter is laid out on one virtual canvas (RTL or LTR), so page navigation is a pan/zoom retarget — no reloads, no DOM churn. Ships double-page spreads with wide-page detection, per-page overrides (insert blank / force solo), reading direction, rotation, smart crop, tap-zone presets, skip-blank, in-place chapter swaps, progress persistence, an image proxy, and an optional annotation layer via etcher.

Reading vertical-scroll comics? That's the sibling package — manhwa — a long-strip reader for webtoons/manhwa/manhua with panel snap, auto-reader, and infinite chapter scrolling.


Install

def deps do
  [
    {:manga, "~> 0.1"}
  ]
end

Wire it up

manga is built on the manhwa core, so the plumbing is the same contract: one Manhwa.Store implementation and the same config :manhwa keys (see the manhwa docs). Mount the manga macro:

# router.ex
import Manga.Router

scope "/" do
  pipe_through [:browser, :require_auth]
  manga_reader "/reader/manga"           # → /reader/manga/:source/:slug/:chapter
end

JS — import both viewers' hooks in assets/js/app.js:

import "../../deps/fresco/priv/static/fresco.js"
import "../../deps/fresco_strip/priv/static/fresco_strip.js"

CSS — add both packages to your Tailwind v4 sources (daisyUI v5 required):

@source "../../deps/manhwa";
@source "../../deps/manga";

See the manhwa README for the Store contract and the optional adapters (annotations, GIF picker, etcher host).

One behavior worth knowing: since the core tracks a per-series (and per-device) reading mode, a series whose saved mode is "scroll" renders through the strip reader on the same route — so mixed libraries read correctly without extra wiring.

License

MIT