Rust getting started

Generate your first PDF
inside the Rust process

Add one crate, call one function, and keep the full rendering pipeline inside your application.

Rust 1.88+ · crates.io

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(())
}
Result

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.