Install the crate
From an existing Cargo project, add the current ironpress release:
cargo add ironpress
The default build needs no browser executable or system library. Your project must use Rust 1.88 or later.
Create an HTML PDF
The convenience function returns the complete PDF as Vec<u8>. Your application decides where those bytes go.
use ironpress::html_to_pdf;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let html = r#"
<style>
@page { size: A4; margin: 18mm; }
h1 { color: #295dff; }
</style>
<h1>Hello from Rust</h1>
"#;
let pdf = html_to_pdf(html)?;
std::fs::write("output.pdf", pdf)?;
Ok(())
}
Running cargo run writes a complete output.pdf without starting a subprocess.
Render Markdown
Markdown uses the same renderer and returns the same byte type:
use ironpress::markdown_to_pdf;
let pdf = markdown_to_pdf("# Release notes\n\nEverything shipped.")?;
std::fs::write("release-notes.pdf", pdf)?;
Reuse a configured converter
Use HtmlConverter when several settings must compose or multiple documents share one policy.
use ironpress::{HtmlConverter, Margin, PageSize};
let converter = HtmlConverter::new()
.page_size(PageSize::LETTER)
.margin(Margin::new(36.0, 48.0, 36.0, 48.0))
.header("Quarterly report")
.footer("Page {page} of {pages}");
let pdf = converter.convert("<h1>Results</h1>")?;
The builder is immutable from the caller's perspective: each method
returns the configured value. Reuse the final converter for repeated
convert or convert_markdown calls.
Load fonts, images, and styles safely
Relative URLs are denied until you establish a local boundary.
base_path resolves URLs and also becomes the default
authorization root. Use resource_root only when shared
assets live in a broader parent directory.
use ironpress::HtmlConverter;
use std::path::Path;
let font = std::fs::read("assets/Inter.ttf")?;
let pdf = HtmlConverter::new()
.base_path(Path::new("templates"))
.resource_root(Path::new("."))
.add_font("Inter", font)
.convert(r#"
<style>body { font-family: Inter }</style>
<img src="assets/logo.png">
"#)?;
Remote HTTP resources require cargo add ironpress --features remote
plus an explicit NetworkPolicy. They are not enabled by default.
Handle errors and choose the right renderer
Conversion methods return Result. Propagate or map
IronpressError at your application boundary instead of
assuming every template is valid.
- HTML sanitization is enabled by default.
- JavaScript and live browser DOM behavior are not supported.
- Local paths stay inside the canonical resource boundary.
- Use a headless browser when exact Chrome print behavior is required.
Go further
Move from the first conversion to the API surface that fits your service.