A browser-native, self-contained reader with responsive spreads, page curling, a thumbnail overview, zoom, fullscreen, sharing, keyboard navigation, and inline isolated styles. It is a private @williamsny package.
This public repository contains no client documents or client imagery. The included Field Notes demo PDF and its raster pages are wholly fictional assets generated from scripts/generate-demo-pdf.py.
Open the Field Notes demo. It is deployed to GitHub Pages from the synthetic demo assets in this repository.
npm install @williamsny/flipbookThe reader is browser-only. Give its host container a non-zero height; it mounts all reader UI into an isolated Shadow DOM and needs no CSS import.
npm ci
python3 -m venv .venv
. .venv/bin/activate
python -m pip install -r scripts/requirements-demo.txt
npm run demo:assets
npm run demoOpen the local URL Vite reports to review the synthetic Field Notes document. npm run demo:build produces a static demo build in dist-demo/.
import { mountFlipbook } from "@williamsny/flipbook";
const reader = mountFlipbook(
document.querySelector("#brochure"),
["/pages/01.jpg", "/pages/02.jpg", "/pages/03.jpg"],
{
title: "Field Notes",
subtitle: "A fictional document",
mark: "FN",
onPageChange({ page, visiblePages }) {
history.replaceState(null, "", `#page=${page}`);
},
},
);
reader.goTo(12);
reader.destroy();mountFlipbook owns the complete reader, including its styles. It mounts into a Shadow DOM, so
consumer CSS is not required and reader styles do not leak out. The surrounding application owns
page data, deeper product branding, links, analytics, and layout allocation for the container.
container must be an HTMLElement. images is an ordered array of image URLs or HTMLImageElements. Existing image elements are never moved; the reader creates its own image nodes from their source URLs.
Options:
title,subtitle,mark,ariaLabelinitialPage(one-based)chrome:"full"(default),"minimal", or"none"; all retain click/drag page turnsonPageChange({ page, visiblePages })
The returned controller exposes page, pageCount, visiblePages, next(), previous(), goTo(page, { animate }), and destroy().
The fullscreen control uses the browser Fullscreen API. When the reader is embedded in an iframe, the embedding page must explicitly grant that permission:
<iframe
src="https://example.com/brochure"
allow="fullscreen"
allowfullscreen
></iframe>Sandboxed embeds must also permit fullscreen. If a browser or embedding page denies the request, the reader leaves the presentation in place and shows a brief unavailable message.
npm run verify checks the JavaScript syntax, builds the ESM bundle and declarations, and inspects the package tarball. Publishing is intentionally configured as restricted:
npm run verify
npm publish