多くの Web application は、最後に PDF export でつまずきます。画面ではきれいに見えても、PDF にすると page break が崩れる。Dynamic data が増えると table が切れる。Font、header、footer、多言語 text、right-aligned amount の扱いが不安定になる。Invoice、order form、audit report、certificate、approval document のような正式な文書では、「だいたい印刷できる」だけでは足りません。

今日紹介する danmolitor/forme は、この問題にかなり正面から向き合っている project です。React/JSX で PDF document を書けますが、内部では HTML を Chrome に印刷させるのではなく、Rust で書かれ WASM に compile された page-aware layout engine を使います。GitHub 上では現在およそ 130 stars7 forks。主な言語は Rust、license は MIT です。Repository は 2026 年 2 月 17 日に作成され、2026 年 5 月 28 日にも更新されています。GitHub Releases の最新 version は v0.10.3 です。

プロジェクト概要

項目内容
リポジトリdanmolitor/forme
Stars約 130
Forks7
主な言語Rust
ライセンスMIT
作成日2026 年 2 月 17 日
最近の更新2026 年 5 月 28 日
最新 releasev0.10.3

Browser print ではなく、page layout engine

Forme の設計で重要なのは、PDF を「印刷された Web page」ではなく「paged document」として扱うことです。README で強調されているのは、content が page に流し込まれ、page break が正しい場所で起き、table や text が page boundary で壊れないことです。

これはよくある approach と少し違います。Puppeteer のような tool は browser rendering を再利用できる一方で、page break は CSS と print behavior に依存します。react-pdf のような project は component model を提供しますが、複雑な pagination では workaround が必要になることがあります。Forme は、PDF のために component と layout system を設計し直す方向です。

基本的な書き方は React に近いです。

import { Document, Page, View, Text } from '@formepdf/react';
import { renderDocument } from '@formepdf/core';

const pdf = await renderDocument(
  <Document>
    <Page size="Letter" margin={36}>
      <Text style={{ fontSize: 24, fontWeight: 'bold' }}>
        Invoice #2026-001
      </Text>
      <View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
        <Text>Consulting</Text>
        <Text>$800.00</Text>
      </View>
    </Page>
  </Document>
);

Result は PDF bytes なので、file として保存したり、API response にしたり、email attachment にしたり、browser で生成して download したりできます。

Page break が主役になる理由

PDF generation の難しさは、たいてい一ページ目ではなく、data が長くなった後に出ます。Order line が複数 page にまたがる。Table header を各 page で繰り返したい。Paragraph の最後の一行だけを page bottom に残したくない。Right-aligned amount が width calculation の問題で page 外に出る。Grid row が収まらないとき、cell ごとではなく row 全体を次 page に送りたい。

Forme は README と release notes の両方で、この種の細かい layout issue に触れています。Widow/orphan control、table overflow、repeating table header、CSS Grid、flex wrap などが page boundary を考慮して実装されています。最新の v0.10.3 も text layout の bug-fix release で、flex row の中に固定 width の text を置いたとき、right aligned text が page 外へ押し出される regression を直しています。

つまり Forme が目指しているのは、「PDF ファイルを作れる」だけではありません。実際の business data を流し込んだときに、文書として破綻しないことです。Invoice、contract、report のような出力では、この差が production readiness に直結します。

React component だが、Web DOM ではない

Forme には DocumentPageViewTextImageTableSvgQrCodeBarcodeCanvas、chart components、form components、repeating header/footer 用の Fixed などがあります。Template を component として分割できるので、巨大な HTML string や template literal を保守するより読みやすくなります。

ただし、これは browser DOM の完全な代替ではありません。Style は CSS や React Native に近い感覚ですが、目的は PDF document に必要な layout と visual property を安定して表現することです。README には flex、grid、absolute positioning、border radius、gradient background、text overflow、image、link、bookmark、dynamic page number、Tailwind class conversion などが挙げられています。

この境界は大事です。既存の Web page をそのまま PDF にしたいなら、browser print のほうが早い場合があります。一方、PDF を独立した template として保守し、code review し、test したいなら、Forme の component model はかなり自然です。

Font、language、accessibility

PDF document では font と language が問題になりやすいです。Customer name、international address、多言語の規約文、right-to-left text などが入ると、単純な text rendering では足りません。Forme README では、rustybuzz による OpenType shaping、ligature、kerning、contextual forms、automatic hyphenation、BiDi text、font registration、font fallback、font subsetting などが説明されています。

さらに document language、PDF/UA accessibility、PDF/A archival も扱います。Simple invoice では初日から必要ないかもしれませんが、government、finance、healthcare、long-term archive の領域では重要です。多くの PDF tool は最初に見た目だけを重視し、あとから accessibility や archival requirement に苦しみます。Forme は少なくとも design scope にそれらを入れています。

Dev server と VS Code extension

PDF template の debugging は遅くなりがちです。Template を少し変え、PDF を再生成し、file を開き、zoom してずれを探す。この loop はすぐ時間を奪います。Forme には forme dev があり、live preview と debug overlay を使えます。Element を click して computed styles を確認することもできます。

VS Code extension も用意されており、PDF preview、component tree、hover highlight、inspector panel などを提供します。これは template maintenance で実用的です。PDF の bug は JavaScript exception として出るとは限りません。「なぜこの text が二ページ目で消えたのか」「なぜ table column の幅がずれたのか」を、visual と source position の両方から追えるのは助かります。

複数 runtime と言語 binding

Forme は Node.js server だけの tool ではありません。README では @formepdf/core/browser を使って browser 上で PDF を生成する方法も紹介されています。Vite、Next.js、Remix など、WASM を扱える bundler で使える設計です。Release notes には npm package、Rust crate、Python package、Go package、Docker image、VS Code extension などの upgrade path も出ています。

これにより、いくつかの運用形態に合います。

  • Backend API が request ごとに PDF を生成する。
  • Frontend が browser 側で user document を生成する。
  • Internal CLI が batch job として文書を出す。
  • Worker や edge runtime で軽量に document rendering する。
  • 他言語 service から SDK や container 経由で同じ engine を使う。

一方で、runtime が多いほど integration detail も増えます。v0.10.1 では Cloudflare Workers の WASM import に関する問題が修正されています。良い点は、release notes がかなり具体的で、実際にこの境界を磨いている様子が見えることです。

Puppeteer や react-pdf との使い分け

Forme README は、自分自身を react-pdf や Puppeteer と比較しています。強みは page break、table pagination、text shaping、hyphenation、accessibility、PDF-specific feature にあります。Rust/WASM engine により、PDF のために browser process を立ち上げる必要もありません。

ただし、すべての case で Forme が最短とは限りません。既存の複雑な HTML page があり、「現在の画面をそのまま印刷したい」だけなら Puppeteer はまだ有力です。Browser CSS、Canvas、third-party chart library、interactive state をそのまま使いたい場合、Forme の component tree へ移す cost がかかります。

Forme が合うのは、PDF を最初から独立した output として作る project です。Template structure が明確で、data shape が安定していて、pagination quality が重要で、document の構造を code review で読みたい場面に向いています。

向いている team

Forme は次のような team に合いそうです。

  • SaaS product で invoice、quote、contract、audit report を安定して生成したい。
  • Internal system に dynamic table や multi-page report が多い。
  • Team が React に慣れていて、PDF template も component として管理したい。
  • Puppeteer based print が pagination、font、performance の面でつらくなっている。
  • Browser や edge で PDF を生成したいが、full browser dependency は避けたい。
  • PDF/A、PDF/UA、bookmark、link、QR code、barcode などの document feature が必要。

たまに simple page を一枚 export するだけなら、Forme はやや重く見えるかもしれません。しかし PDF が product の一部なら、かなり検討しやすい方向です。

注意したい境界

Forme はまだ若い project です。Repository の作成日は新しく、API と周辺 package は速く動いています。最近の releases にも layout や packaging の修正が含まれています。Production で使う前には、自分たちの実 template と data で regression test を作るべきです。

また、Forme は「すべての CSS を完全に support する」tool ではありません。CSS-like property や Tailwind conversion はありますが、PDF component tree と browser DOM は別物です。既存 Web template の移植では、一対一で写すより、PDF document として構造を設計し直すほうが安全です。

最後に、PDF correctness は visual test で守るのがよいです。v0.10.3 の release notes では、PDF bytes は deterministic でも、right-aligned text が page 外に出て見えなくなる case が説明されています。File が生成されたことだけではなく、重要 page が実際に正しく render されることを確認したいところです。

まとめ

danmolitor/forme は、狙いがはっきりした PDF generation project です。React/JSX で developer experience を保ち、Rust/WASM で page-aware layout を担い、table、font、text shaping、browser generation、accessibility といった PDF の本当の難所を中心に置いています。

まだ若い project ですが、「HTML を印刷して PDF にする」よりも、正式文書システムに向いた設計です。Application の PDF が user に何度も download、archive、audit、forward される重要な file なら、Forme は技術選定リストに入れる価値があります。

リポジトリ:https://github.com/danmolitor/forme