32 lines
1.4 KiB
Markdown
32 lines
1.4 KiB
Markdown
# PDF Generation: Imprintor instead of Chromium
|
|
|
|
## Decision
|
|
|
|
For PDF generation we use **Imprintor** (`{:imprintor, "~> 0.6.0"}`) with
|
|
**Typst** templates, rather than a Chromium-based renderer (Puppeteer, Chrome
|
|
Headless, etc.). Implemented in `lib/mv/membership/members_pdf.ex`, template at
|
|
`priv/pdf_templates/members_export.typ`.
|
|
|
|
## Rationale (Imprintor over Chromium)
|
|
|
|
- **Resource efficiency:** no full browser instance in memory, no
|
|
browser-rendering pipeline on the CPU.
|
|
- **Smaller Docker images:** no Chromium install (saves several hundred MB);
|
|
works in minimal images (e.g. Alpine), with no system dependencies
|
|
(Chromium, ChromeDriver) to ship or keep updated.
|
|
- **Elixir-native:** integrates with the BEAM and Elixir error handling instead
|
|
of managing an external browser process; faster generation and easier
|
|
parallelism (no browser startup or instance management).
|
|
- **Smaller attack surface:** no browser engine with its own CVE stream.
|
|
|
|
## When Chromium would still be warranted
|
|
|
|
A Chromium-based renderer makes sense when the document requires JavaScript
|
|
execution, dynamic JS-rendered content, modern web CSS features, or full-page
|
|
screenshots of web pages — none of which apply to our static, template-driven
|
|
exports.
|
|
|
|
## Usage in this project
|
|
|
|
Member export as PDF (member lists / reports) and other static, predefined
|
|
documents (e.g. membership certificates).
|