← All updates

QR codes as native PDF vector graphics

New qr() builder generates scannable QR codes — versions 1–40, all four ECC levels, auto-mode selection, dynamic values via {{template}} placeholders, no font, no rasterisation.

dslbuilderqr-codes

Templates can now render QR codes alongside the Code 39 / Code 128 barcodes we shipped earlier today. The new qr() DSL builder produces QR codes as native PDF vector graphics — no font to embed, no image to fetch, no rasterisation.

qr("https://pay.example.com/inv/{{invoice.number}}", {
  ecc: "M", // "L" | "M" (default) | "Q" | "H"
  size: 120, // total width/height in pt (square)
  alt: "Scan to pay invoice {{invoice.number}}",
});

The value accepts {{template}} placeholders and resolves at render time, so the same template renders a different code for every payload. The encoder auto-selects the smallest QR version that fits (21×21 up to 177×177 modules), picks the most efficient encoding mode (numeric, alphanumeric, or UTF-8 byte), and chooses the lowest-penalty mask per the ISO/IEC 18004 spec.

Pick the error-correction level for the conditions the code will live in: L for clean on-screen URLs, M (default) for everyday print, Q for receipts and dim lighting, H for thermal labels and anywhere damage is likely. Higher ECC means a larger symbol for the same payload — aim for a module width of at least 1pt so phone cameras can resolve it reliably.

The three invoice templates in the library (Classic, Modern, Compact) now include a "scan to pay" QR next to their payment-instructions block. Skill: see pdf-template-author.md §QR Codes.