EN

NewPrint-ready pages for React

Imposia

Turn HTML and CSS into real pages. Preview them in your app, then print or save as PDF — all in the browser.

pnpm add @imposia/reactimport { ImposiaPageViewer } from "@imposia/react"

WHY IMPOSIA

Everything you need to ship pages

Keep the HTML and CSS you already have. Imposia handles the pages.

  • Real pages from HTML

    Lay out existing markup into sized pages with margins, running heads, and page numbers.

  • Native print and PDF

    print() opens the browser's print dialog. Readers print on paper or choose Save as PDF.

  • No half-built frames

    The next set of pages is finished off-screen. The preview swaps only when layout is complete.

  • One document everywhere

    Preview and print read the same committed pages, so page counts never drift.

  • React-first, framework-free

    Drop in <ImposiaPageViewer />, or drive @imposia/core from any framework.

  • Controlled asset loading

    Images, fonts, and stylesheets go through your assetResolver. No surprise network requests.

HOW IT WORKS

HTML in. Pages out.

One component, three steps, and the same pages on screen and on paper.

  1. 01

    Pass your HTML

    Give the viewer an HTML string with page size and margins. Your CSS still applies.

  2. 02

    Imposia paginates

    Pages are laid out in a staging frame. The last finished set stays on screen until the new one is ready.

  3. 03

    Preview, print, save

    Readers flip through pages in your app, then print or save as PDF from the same result.

import { useRef } from "react";
import { ImposiaPageViewer, type ImposiaPageViewerHandle } from "@imposia/react";
import "@imposia/react/styles.css";

export function Report({ html }: { html: string }) {
  const viewer = useRef<ImposiaPageViewerHandle>(null);
  return (
    <>
      <ImposiaPageViewer
        ref={viewer}
        source={{ html }}
        documentOptions={{ page: { size: "A4", margin: "18mm" } }}
      />
      <button onClick={() => viewer.current?.print()}>
        Print or save as PDF
      </button>
    </>
  );
}

BENCHMARKS

Measured, not claimed.

Same fixtures, same browser, recorded by the repository's benchmark script. Every number re-runs from a fresh clone.

Apple M4 · Chromium 149 · median of 7

Edit → updated pages
30ms
One-word edit in a 50-page report until the new pages are committed
200 pages
131ms
Pagination of a 200-page document, from HTML to committed pages
print() → dialog
1.1ms
From the print() call until the browser's print dialog is requested
Partial frames
0frames
Incomplete page sets shown on screen during 20 rapid updates
Live edit latency · 50 pageslower is better
  • Imposia30 ms
  • Paged.js217 ms
  • Vivliostyle212 ms
Pagination · 200 pageslower is better
  • Imposia131 ms
  • Paged.js849 ms
  • Vivliostyle2154 ms
Bundle sizefull browser bundle, gzip, lower is better
  • Imposia74.7 KiB
  • Paged.js94.2 KiB
  • Vivliostyle215.2 KiB

Imposia main@4177daa · Paged.js 0.4.3 · Vivliostyle 2.45.2 · harness in scripts/benchmark-compare.ts and scripts/benchmark.ts · pnpm benchmark:compare
Paged.js and Vivliostyle have no incremental update, so an edit renders them again from scratch. All three produced the same page counts.
Current Imposia bundle measurement: Imposia 0.8.1 · 2026-10-13 · pnpm bundle:size

PACKAGES

Start with React. Go lower when you need to.

View on npm

Your HTML is already a document.

Add one component and give it pages.

Read the docs