DEV Community

tokagemushi
tokagemushi

Posted on • Originally published at zenn.dev

I Built a Zero-Dependency Manga Viewer in Vanilla JavaScript πŸ“–

Why I Built This

I wanted to display manga on my website, but every existing viewer was either too heavy, required React/Vue, or needed a complex build setup. I just wanted to drop in two files and have a working manga reader.

So I built one from scratch.

Zero Dependencies

No React. No Vue. No jQuery. Just one JavaScript file + one CSS file.

Manga viewers are often added to existing sites. The moment you depend on a framework, the barrier to adoption skyrockets.

<link rel="stylesheet" href="manga-viewer.css">
<div id="viewer"></div>
<script type="module">
  import MangaViewer from './manga-viewer.js';
  new MangaViewer({
    container: '#viewer',
    pages: ['page-001.jpg', 'page-002.jpg'],
    direction: 'rtl',
  });
</script>
Enter fullscreen mode Exit fullscreen mode

Also available via npm:

npm install @tokagemushi/manga-viewer
Enter fullscreen mode Exit fullscreen mode

Features

  • Spread view β€” 2-page spread on desktop, single page on mobile (auto-switches)
  • RTL / LTR β€” Japanese manga reads right-to-left; this handles it natively
  • Swipe navigation β€” Mobile-native feel with momentum
  • Pinch-to-zoom β€” Zoom in, drag to pan, page turns when you hit the edge
  • Bookmarks β€” One tap to add, long press for the list
  • Reading progress β€” Auto-saves where you left off
  • Fullscreen / keyboard nav / preloading

Implementation Details

Pinch-to-Zoom

Tracking two-finger distance and center point to calculate zoom level. The key is zooming relative to the pinch center, not the viewport center.

RTL Support

Japanese manga reads right-to-left. This means every interaction reverses: swipe direction, slider direction, spread layout, tap zones. All controlled by a single direction config.

Spread Slot Design

One slot = one or two pages. The cover page is always displayed as a single page. Subsequent pages pair up automatically for the spread view.

Bookmark Storage

Two strategies: localStorage (default) and API-backed. If the API call fails, it gracefully falls back to localStorage.

Demo

I'm using "Black Jack ni Yoroshiku" Volume 1 (209 pages) by Shuho Sato, available under his free secondary use license.

πŸ‘‰ Try the demo

Links

What's Next

I'm planning a Pro version with analytics, DRM, theme builder, and creator dashboards β€” the WordPress model (free OSS core β†’ paid hosted service).

Feedback, issues, and PRs welcome!

Top comments (0)