7. When documents get large
Before this: You can build documents in Node and the browser.
buildDocumentPDFBytes returns the finished document as one array, which is right for almost everything. Past a few thousand pages you want the bytes to leave as they are produced instead.
import { buildDocumentPDFStreamTrue, streamToFile } from 'pdfnative';
await streamToFile(
buildDocumentPDFStreamTrue({ title: 'Big', blocks }),
'big.pdf',
);
There are two streaming variants and the difference matters. buildDocumentPDFStream assembles the whole binary, then chunks it โ simple, but it joins everything into one JavaScript string, and V8 caps a single string at roughly 512 MB. buildDocumentPDFStreamTrue never joins, so it has no such ceiling. Prefer the second at scale.
Two things streaming cannot do
Both need a second pass over the finished document, which is what streaming exists to avoid. Both throw a clear error rather than misbehaving:
tocblocks โ a table of contents needs page numbers that are not known yet.{pages}in a header or footer template โ same reason. Use{page}alone.
What it does not buy you
Streaming is often described as constant-memory. That is not quite true here, and the difference is worth knowing before you rely on it: every PDF object is built before the first chunk is emitted, so peak memory still scales with output size. Budget for roughly twice your expected file size. The streaming guide states the profile precisely.
The scale playground generates 100,000 pages in a browser tab and shows the measured throughput.
Tip: Alt + โ / โ moves between steps.