SKALD

Java · PDF 2.0 · Apache 2.0

The PDF library businesses actually ship.

Skald writes compact, Unicode, PDF 2.0 documents with no third-party runtime dependencies. Invoices, statements, clothing stickers, packing slips, tickets, and reports — generated on JDK 27, verified by independent renderers.

Runtime deps
0
Output
PDF 2.0 only
Typical invoice
~25–35 KB
Modules
core · layout · barcode · invoice-no · sign · image · optimize · jpegli

Documents that look finished.

These files are generated by the library in CI. Open them. They are the product.

Modern invoice with payment QR

Invoice with payment QR

First-page letterhead, continuing chrome, line table, and a machine-readable QR.

invoice.pdf
93 by 35 millimetre clothing sticker

93×35 mm clothing sticker

ISO EAN-13, SKU, origin, size, composition. Compact font subset, ~13 KB.

sticker.pdf
Event ticket with QR code

Event ticket

Vector QR on a small page. Decodable after print, no raster logo required.

ticket.pdf
Statement of account

Statement of account

Repeating table headers, reserved footer, embedded Unicode, object streams.

statement.pdf
Packing slip with tracking QR

Packing slip

Warehouse paper with a tracking QR. Same API as the invoice.

packing-slip.pdf
A4 sheet of clothing stickers

A4 sticker sheet

N-up clothing labels for a desktop printer. One call, many SKUs.

sticker-sheet.pdf

Built for the documents you generate every day.

Not a 1.x compatibility museum. Not an HTML engine. A writer for commercial PDFs.

Honest layout

Nested tables, row spans, repeating footer rows, and mixed columns. Italic is a real face. A custom brand font falls back to Skald Sans for missing glyphs.

Safe composition

Merge and stamp received supplier files. Launch and JavaScript actions are stripped. Indirect /Contents and /Annots resolve. Output is always PDF 2.0.

Symbols that scan

EAN-13, UPC-A, Code 128, GS1-128, and QR are vector ImageSource values. Tests decode them with ZXing after PDFBox rendering — not by inspecting our own bits.

Tiny subsets

TrueType is subset and embedded once per face. Unused OpenType layout tables are dropped. A Latin invoice stays tens of kilobytes, not hundreds.

Zero runtime deps

Core JPMS modules use only the JDK. Received-PDF optimization can optionally add Glimt's bundled JPEGli encoder without PDFBox or server executables.

Apache 2.0

Use it in commercial products without an AGPL conversation. IBM Plex faces ship under the SIL Open Font License.

Start in one dependency.

Release 1.16.2 requires JDK 27. Java packages stay org.skaldpdf.

dependencies {
    implementation("no.beint.skaldpdf:skald-layout:1.16.2")
    implementation("no.beint.skaldpdf:skald-invoice-no:1.16.2")    // optional Norwegian invoice
    implementation("no.beint.skaldpdf:skald-label-sticker:1.16.2") // optional
}
byte[] invoice = Pdf.create(document -> {
    document.setMargins(40, 40, 40, 40);
    document.setFirstHeader(page -> new Paragraph("Northstar Ledger · original"));
    document.setFooter(18, page -> new Paragraph(page.pageNumber() + " / " + page.pageCount())
        .setTextAlignment(TextAlignment.CENTER));
    document.add(new Paragraph("Invoice 2026-1001").bold().setFontSize(20));
    document.add(new Image(new QrCode("https://pay.example/inv/2026-1001")).scaleToFit(72, 72));
});

Requires JDK 27+. See the repository, capability matrix, and roadmap.

How it sits next to the usual options.

Skald iText OpenPDF PDFBox
License Apache 2.0 AGPL or commercial LGPL Apache 2.0
Runtime deps None Several Several Several
Default output PDF 2.0 only 1.x and 2.0 1.x heritage 1.x / mixed
Best at Generating business documents Broad historical API iText 4 continuation Parsing and inspection