typstgen 0.1.0

Compile existing .typ files to PDF with an embedded Typst engine — no external typst binary, config-driven template resolution. Usable as CLI, Rust lib, and Wasm.
Documentation

typstgen

Compile an existing .typ file to PDF. No external typst binary, no subprocess — Typst runs embedded as a Rust library. Template resolution is config-driven instead of hardcoded.

your-document.typ  +  typstgen.toml (template_paths)  →  your-document.pdf

Usable three ways from one crate:

  • CLI (cli feature, default): typstgen compile input.typ
  • Rust library (always available): typstgen::compile(path, &config)
  • Wasm (wasm feature): source and imports supplied as a JSON virtual filesystem

Why

docgen already does PDF generation from Typst, but grew into a client/project-management tool along the way and only ever hardcoded its template lookup paths. typstgen is the minimal version of the same idea: one job (.typ in, PDF out), with the template directory resolved from config instead of baked in.

See docs/PLAN.md for the full rationale, lessons carried over from docgen, and the architecture reused from renderreport (embedded Typst, feature-gated CLI/Wasm, embedded-fonts-only on Wasm).

Quick start

cargo install typstgen
typstgen compile documents/concepts/2026/example.typ
# typstgen.toml
# Each path is a virtual filesystem root for absolute imports. They are
# searched in order; the first existing path is used.
template_paths = [".", "./templates"]
use typstgen::{compile, Config};

let config = Config::load(None)?;
let pdf_bytes = compile("example.typ".as_ref(), &config)?;
std::fs::write("example.pdf", pdf_bytes)?;

Wasm

Build with cargo build --target wasm32-unknown-unknown --no-default-features --features wasm. Pass source and importable text files as JSON; the returned bytes are a PDF:

compile(JSON.stringify({
  source: '#import "templates/shared.typ": title\n#title',
  files: { 'templates/shared.typ': '#let title = [Hello]' },
}))

License

MIT