Forme - JSX でページ分割に強い PDF を生成する
多くの 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 stars、7 forks。主な言語は Rust、license は MIT です。Repository は 2026 年 2 月 17 日に作成され、2026 年 5 月 28 日にも更新されています。GitHub Releases の最新 version は v0.10.3 です。
プロジェクト概要
| 項目 | 内容 |
|---|---|
| リポジトリ | danmolitor/forme |
| Stars | 約 130 |
| Forks | 7 |
| 主な言語 | Rust |
| ライセンス | MIT |
| 作成日 | 2026 年 2 月 17 日 |
| 最近の更新 | 2026 年 5 月 28 日 |
| 最新 release | v0.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 には Document、Page、View、Text、Image、Table、Svg、QrCode、Barcode、Canvas、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 は技術選定リストに入れる価値があります。