renderreportv0.7.0renderreport.casoon.de

CASOON Open Source

Data in, report out.

renderreport builds PDF reports from components and theme tokens. Describe the report in Rust or JSON; the engine writes the Typst source and compiles it in-process, with PDF/UA-1 enforced. No typst binary, no Typst to learn.

health-check.jsonJSON
{
  "template_id": "default",
  "title": "Website Health Check",
  "subtitle": "shop.example.com — October 2026",
  "metadata": {
    "date": "2026-10-12",
    "author": "Web Team"
  },
  "components": [
    {
      "type": "section",
      "data": {
        "title": "Summary",
        "level": 1
      }
    },
    …
  ]
}

renderreport render health-check.json

Page 2 of health-check.pdf: a Summary section with three score cards (Performance 78, Accessibility 91, SEO 64), four progress bars for pages passing Core Web Vitals, and a high-severity finding about hero images without size hints.

34 KiB

cargo add renderreport
curl -fsSL https://raw.githubusercontent.com/casoon/renderreport/main/install.sh | sh
npm install @casoon/renderreport
MITcrates.io 0.7.0Rust 1.92+Typst 0.15PDF/UA-1
built-in components in 8 categories
80
external typst binaries or subprocesses
0
ways in: Rust, CLI, npm, Wasm
4
PDF standard enforced on every render
UA-1

What it does

  1. Components, not markup

    Score cards, findings, tables, timelines, pricing cards and 75 more. Each takes plain data; layout hints keep headings with their content and cards in one piece.

  2. Theme tokens

    Colours, fonts, spacing and margins are named tokens that every component reads. Merge the default theme, a pack theme and your own, token by token.

  3. Accessible by default

    Every PDF is tagged and checked against PDF/UA-1 while it is written. A missing title, language or alt text fails the render instead of shipping silently.

  4. Runs where your data is

    Rust library, a CLI that reads JSON (also via npm), and a Wasm build for JavaScript hosts such as Cloudflare Workers, with bundled fonts.

How it works

Every way in produces the same render request. The engine merges the themes, writes the Typst source and compiles it in-process.How a report is rendered walks through each step.

Focus
From data to PDF
From data to PDFThe Rust builder, the CLI and the Wasm build all produce a RenderRequest. The engine merges the themes, writes the Typst source and compiles it in-process; the PDF is written with PDF/UA-1 enforced, or the render fails with a Typst diagnostic.InputEngineOutputRust builder → RenderRequestJSON → RenderRequest: serdeRenderRequest → Merge themesMerge themes → Typst sourceTypst source → .typ string: stop hereTypst source → Embedded Typst 0.15Embedded Typst 0.15 → PDF/UA-1 met?PDF/UA-1 met? → PDF: yesPDF/UA-1 met? → Typst diagnostic: noserdestop hereyesnoRust builder – engine.report(…)Rust builderengine.report(…)JSON – CLI, npm, WasmJSONCLI, npm, WasmRenderRequest – components, theme, metadataRenderRequestcomponents, theme, metadataMerge themes – default → pack → requestMerge themesdefault → pack → requestTypst source – tokens, page setup, componentsTypst sourcetokens, page setup, componentsEmbedded Typst 0.15 – virtual files, fontsEmbedded Typst 0.15virtual files, fonts.typ string – render_typ.typ stringrender_typPDF/UA-1 met?PDF/UA-1 met?PDF – render_pdfPDFrender_pdfTypst diagnostic – no PDF writtenTypst diagnosticno PDF written

Source: src/engine/mod.rs, src/render/typst_compile.rs

Show chart data
Data for From data to PDF
StepKindLaneLeads to
Rust builderstartInputRenderRequest
JSONstartInputRenderRequest (serde)
RenderRequeststepInputMerge themes
Merge themesstepEngineTypst source
Typst sourcestepEngine.typ string (stop here), Embedded Typst 0.15
Embedded Typst 0.15stepEnginePDF/UA-1 met?
.typ stringendOutput
PDF/UA-1 met?decisionOutputPDF (yes), Typst diagnostic (no)
PDFendOutput
Typst diagnosticendOutput
Focus
From data to PDF
From data to PDFThe Rust builder, the CLI and the Wasm build all produce a RenderRequest. The engine merges the themes, writes the Typst source and compiles it in-process; the PDF is written with PDF/UA-1 enforced, or the render fails with a Typst diagnostic.InputEngineOutputRust builder → RenderRequestJSON → RenderRequest: serdeRenderRequest → Merge themesMerge themes → Typst sourceTypst source → .typ string: stop hereTypst source → Embedded Typst 0.15Embedded Typst 0.15 → PDF/UA-1 met?PDF/UA-1 met? → PDF: yesPDF/UA-1 met? → Typst diagnostic: noserdestop hereyesnoRust builder – engine.report(…)Rust builderengine.report(…)JSON – CLI, npm, WasmJSONCLI, npm, WasmRenderRequest – components, theme, metadataRenderRequestcomponents, theme, metadataMerge themes – default → pack → requestMerge themesdefault → pack → requestTypst source – tokens, page setup, componentsTypst sourcetokens, page setup, componentsEmbedded Typst 0.15 – virtual files, fontsEmbedded Typst 0.15virtual files, fonts.typ string – render_typ.typ stringrender_typPDF/UA-1 met?PDF/UA-1 met?PDF – render_pdfPDFrender_pdfTypst diagnostic – no PDF writtenTypst diagnosticno PDF written

Source: src/engine/mod.rs, src/render/typst_compile.rs

Show chart data
Data for From data to PDF
StepKindLaneLeads to
Rust builderstartInputRenderRequest
JSONstartInputRenderRequest (serde)
RenderRequeststepInputMerge themes
Merge themesstepEngineTypst source
Typst sourcestepEngine.typ string (stop here), Embedded Typst 0.15
Embedded Typst 0.15stepEnginePDF/UA-1 met?
.typ stringendOutput
PDF/UA-1 met?decisionOutputPDF (yes), Typst diagnostic (no)
PDFendOutput
Typst diagnosticendOutput

Rendered by renderreport

All examples →

This browser does not show PDFs inline. Use the links below.

Open health-check.pdf · Download health-check.pdf (34 KiB)

examples/requests/health-check.json, rendered with the CLI. examples/regenerate.sh rebuilds every PDF on this site from the current checkout.

examples/requests/health-check.pdf

Quickstart

Three steps from data to a PDF. The documentation covers components, themes, the JSON format and Wasm.

  1. Add the crate with cargo add renderreport.
  2. Build a report from components with engine.report(…).
  3. Write the bytes from engine.render_pdf to a file.
src/main.rsRust
use renderreport::prelude::*;

fn main() -> renderreport::Result<()> {
    let engine = Engine::new()?;

    let report = engine
        .report("default")
        .title("Website Health Check")
        .add_component(ScoreCard::new("Accessibility", 91))
        .add_component(Finding::new(
            "212 URLs return a redirect chain",
            Severity::Medium,
            "Old product URLs redirect twice.",
        ))
        .build();

    std::fs::write("report.pdf", engine.render_pdf(&report)?)?;
    Ok(())
}