Typst
Elixir bindings for the Typst typesetting system, powered by a Rust NIF. Generate PDFs, PNGs, and SVGs from Typst markup directly in your Elixir application.
Features
- PDF generation —
render_to_pdf/3 - PNG generation —
render_to_png/3(one image per page) - SVG generation —
render_to_svg/3(one SVG per page) - EEx templating — use familiar Elixir templates to inject dynamic content
- Table formatting — struct-based API for building Typst tables (
Typst.Format.Table) - Virtual file system — pass in-memory assets (images, data) without touching disk
- Font caching — scanned fonts are cached across calls for fast repeated renders
- Precompiled NIF — no Rust toolchain required for most platforms
Installation
Add typst to your list of dependencies in mix.exs:
def deps do
[
{:typst, "~> 0.2"}
]
endUsage
Basic rendering
{:ok, pdf} = Typst.render_to_pdf("= Hello World")
{:ok, [png]} = Typst.render_to_png("= Hello World")
{:ok, [svg]} = Typst.render_to_svg("= Hello World")EEx templating
{:ok, pdf} = Typst.render_to_pdf(
"= Report for <%= name %>\nDate: <%= date %>",
name: "Acme Corp",
date: "2026-03-07"
)Tables
alias Typst.Format.Table
alias Typst.Format.Table.Header
table = %Table{
columns: 3,
content: [
%Header{repeat: true, content: ["Name", "Qty", "Price"]},
["Widget", "10", "$5.00"],
["Gadget", "3", "$12.50"]
]
}
{:ok, pdf} = Typst.render_to_pdf("<%= table %>", table: table)Virtual assets
logo = File.read!("logo.svg")
{:ok, pdf} = Typst.render_to_pdf(
~S|#image(read("logo", encoding: none), width: 6cm)|,
[],
assets: [logo: logo]
)Options
All render functions accept these options:
:extra_fonts— list of directories to search for additional fonts:root_dir— root directory for resolving file paths (default:"."):assets— list of{name, binary}pairs for the virtual file system:trim— trim blank lines left by EEx tags (default:false):cache_fonts— cache scanned fonts across calls (default:true):pixels_per_pt— pixels per pt unit, only forrender_to_png/3(default:1.0)
Documentation
Full documentation is available at hexdocs.pm/typst.
Cutting a new release
- Make the code changes
- Merge into main
git push-
Tag the new version and push:
git tag v0.x.y && git push --tags - Wait for CI to build precompiled binaries
mix rustler_precompiled.download Typst.NIF --all --print-
Checkout the tag:
git checkout v0.x.y mix hex.publishgit checkout main
License
Apache-2.0