Prefer Python? Try PlutoPrint — a Python library built on PlutoBook for easy paged HTML rendering.
PlutoBook is a robust HTML rendering library tailored for paged media. It takes HTML or XML as input, applies CSS stylesheets, and lays out elements across one or more pages, which can then be rendered as Bitmap images or PDF documents.
Note
PlutoBook implements its own rendering engine and does not depend on rendering engines like Chromium, WebKit, or Gecko.
The engine is designed to be robust, lightweight, and memory-efficient, leveraging modern C++ features such as std::pmr::monotonic_buffer_resource to minimize memory fragmentation and optimize allocation performance.
- Introduction
- Motivation
- Features
- Quick Start
- Practical Uses
- Installation Guide
- API Documentation
- Contributions
- License
Programmatically generating PDFs can be surprisingly difficult. Many libraries aim to simplify the task, but they often require learning specialized APIs or handling low-level layout details. In contrast, HTML and CSS are tools that most developers already know. They are expressive, easy to write, and well-suited for describing visual layouts.
You might ask, "Wait, aren't tools like Playwright or Puppeteer already solving this?" They are powerful and feature-rich, but also come with significant overhead. Browser-based renderers are resource-heavy, often requiring gigabytes of memory and complex configurations. They're designed to handle the unpredictable nature of the modern web, including dynamic, JavaScript-heavy content. That makes them ideal for browsing and automation, but excessive for static document rendering.
No one uses a bulldozer to mow a lawn. Not because it can’t, but because it’s overkill. Likewise, PlutoBook isn’t trying to replace your browser. It’s a focused tool designed specifically for high-quality rendering of paginated documents from static HTML or XML sources.
PlutoBook is lightweight, robust, and easy to install. It supports a broad set of modern HTML and CSS features for intuitive layout, while maintaining efficiency and precision. Installation is straightforward and dependency-light. It uses well-established libraries like Cairo, FreeType, HarfBuzz, Fontconfig, Expat, and ICU. Optional support for Curl, TurboJPEG, and WebP extends its capabilities, without the need for a full browser engine.
If your goal is to generate beautiful, paginated documents with precision and control, PlutoBook might be the right tool for the job.
PlutoBook is designed to be easy to get started with. To understand where to begin, it's helpful to first look at how PlutoBook works.
The Book class is the core API class of the PlutoBook library. It serves as the main entry point for working with documents. A Book instance can load content in HTML or XML format, and provides a high-level interface for rendering, exporting to PDF or PNG, and interacting with page structure and metadata.
To create and render a document, you typically start by instantiating a Book, specifying parameters such as the page size (e.g., A4, Letter), page margins, and the media type (MediaType::Print or MediaType::Screen) to control how styles and layouts are interpreted. These parameters define the physical layout and styling context of the document. After that, you load your content using one of the load methods (such as loadHtml or loadXml), and then render it to a canvas or export it as needed.
This example demonstrates the simplest way to use PlutoBook: creating a Book instance with a standard page size (A4), loading a small HTML snippet, and exporting the result as a PDF file named hello.pdf. It showcases the core workflow of loading content and generating a document in just a few lines of code.
PlutoBook supports loading web content directly from remote or local URLs using the loadUrl method. This is useful when rendering existing online documents, integrating live web content, or referencing local assets. Simply provide the URL to the desired resource, and PlutoBook will fetch and parse the content for layout and rendering.
Note
Resource loading is single-threaded and occurs inline with the layout process, which may be slower than in web browsers. JavaScript execution is currently not supported, so some websites may not render correctly. Loading resources over protocols other than file: and data: (for example, HTTP, HTTPS, or FTP) requires libcurl.
Example of loading a webpage from a remote URL:
Example output:
You can load local HTML, SVG, images, or other supported file formats directly by specifying their file paths. This is useful when working with existing documents stored on your filesystem or when generating content offline.
The path can be relative to the current working directory or an absolute path.
Examples:
PlutoBook uses an abstract drawing interface called Canvas, which supports rendering document content to multiple output targets. Two built-in implementations are provided: ImageCanvas and PDFCanvas.
ImageCanvas renders to an in-memory bitmap. It is well-suited for generating PNG images, creating visual previews, or integrating with other graphics systems. The output can be exported to PNG files, or the raw pixel buffer can be accessed for further processing.
PDFCanvas, on the other hand, renders directly to a vector-based PDF stream. It preserves exact layout fidelity, supports selectable text and vector graphics, and is ideal for producing high-quality documents for print, digital publication, or long-term archiving.
Below is a simple example that renders the first few pages of a web article into a single PNG image. It lays the pages side-by-side on one canvas, then saves the result as an image file:
Example output:
In PlutoBook, the viewport refers to the area of the page available for laying out content after accounting for margins. It functions similarly to the browser viewport in web development, where layout calculations are made relative to a visible content area.
The viewport size is automatically determined using:
- Viewport Width = Page Width − Left Margin − Right Margin
- Viewport Height = Page Height − Top Margin − Bottom Margin
You can access the computed dimensions using the methods Book::viewportWidth() and Book::viewportHeight(), which return values in CSS pixels (px).
PlutoBook supports CSS viewport-relative units:
- 1vw is equal to 1% of the viewport width
- 1vh is equal to 1% of the viewport height
For example:
This creates a <div> that spans the full width and half the height of the available viewport space.
These units help create responsive layouts that adapt smoothly to different page sizes and margin settings, ensuring your content looks great regardless of the document’s physical dimensions.
Expected output:
PlutoBook provides a robust HTML and CSS rendering engine that can be integrated into a wide range of workflows. The examples below illustrate how PlutoBook can be used in real-world scenarios.
PlutoBook can render HTML content safely and consistently within an email client. With PlutoBook, developers can implement a custom rendering layer that displays email layouts and styles accurately, without needing a full web browser engine.
For example, the screenshot below shows PlutoBook rendering the first page of a New York Times newsletter:
PlutoBook can be embedded in text editors such as Sublime Text to render HTML output for printing or print preview. This allows developers to generate clean, styled print layouts for their code, Markdown, or other text documents directly within the editor, without needing a separate browser or external PDF tool.
For example, the screenshot below shows PlutoBook rendering a Sublime Text document prepared for printing:
PlutoBook can be integrated into backend services to automatically generate high-quality PDFs or static HTML reports from dynamic data. This is useful for creating invoices, statements, or compliance documents on demand. Designers can style reports using familiar HTML and CSS, making templates easy to maintain.
PlutoBook enables developers to build lightweight e-book readers or document viewers that display paginated, static HTML content with consistent styling, images, and fonts. This is ideal for publishing tools, educational apps, or offline manuals where predictable layout is important.
Rendered page preview of Alice’s Adventures in Wonderland generated by PlutoBook
To build and install PlutoBook, you will need Meson and Ninja installed on your system.
PlutoBook depends on the following external libraries:
- Required: cairo, freetype, harfbuzz, fontconfig, expat, icu
- Optional: curl, turbojpeg, webp (enable additional features)
Note
For faster builds, it is recommended to install precompiled versions of these libraries through your system's package manager. Otherwise, Meson will build them from source, which may significantly increase build time.
For Ubuntu/Debian users, use the following command to install both required and optional dependencies:
Clone the repository, then build and install the project using the following commands:
Detailed information on PlutoBook's functionalities can be found in the header files:
- plutobook.h (C API)
- plutobook.hpp (C++ API)
Contributions to PlutoBook are welcome! Feel free to open issues for bug reports, feature requests, or submit pull requests with enhancements.
PlutoBook is licensed under the MIT License, allowing for both personal and commercial use.