Go · PDF generation

Generate PDFs
from HTML and
Go components.

A precise, testable document engine for production Go services.

One call to render HTML, or a structured component grid built from rows and columns. Invoices, reports, forms, labels, certificates — generated fast, with explicit control over every element on the page.

$ go get github.com/avdoseferovic/paper
Invoice
NO. INV-2026-0481
Billed to
Northwind Trading Co.
Issued
June 8, 2026
Terms
Net 30
Due
July 8, 2026
ItemQtyAmount
Document API — Team1$480.00
Rendering credits12k$240.00
Priority support1$120.00
Total due $840.00
PAPER · A4 · 595×842ptPAGE 1 / 1
FromHTML() → 18ms
12-col grid · deterministic
main.go — one call
package main

import "github.com/avdoseferovic/paper"

func main() {
  doc, _ := paper.FromHTML(invoiceHTML)
  _ = doc.Save("invoice.pdf")
}
layout.go — components
m := paper.New()
m.AddRow(12,
  text.NewCol(8, "Invoice"),
  code.NewQrCol(4, url),
)
doc, _ := m.Generate()  // component tree → PDF
b := doc.GetBytes()
Two authoring paths

Start from HTML. Or compose with components.

Paper gives you both ends of the spectrum — render existing markup in a single call, or build pixel-deterministic layouts from a typed component grid. Mix them freely.

PATH 01

HTML → PDF

Bring your own templates. Pass an HTML string or fragment and get a print-ready PDF back. Ideal for migrating existing documents.

html.go
doc, err := paper.FromHTML(tmpl)
if err != nil { return err }
b64 := doc.GetBase64()
TemplatesFragmentsCSS-awareOne call
PATH 02

Component grid

Compose documents from rows and columns on a 12-column grid. Every element is a typed component you can test, reuse, and inspect.

grid.go
m.AddRow(12,
  text.NewCol(6, header),
  code.NewBarCol(6, sku),
)
Rows / Columns12-col gridTypedReusable
Component library

Every document primitive, built in.

Drop these into any column. Compose your own from them. Each one renders deterministically and can be inspected in tests.

Text
text.New()
Rich text
richtext.New()
Images
image.New()
Tables
table.New()
QR codes
code.NewQrCol()
Barcodes
code.NewBarCol()
Data Matrix
code.NewMatrixCol()
Approved
Pending
Checkboxes
checkbox.New()
Avdo S.
Signatures
signature.New()
Lines
line.New()
Page 3 of 12
Page numbers
RegisterFooter()
Headers & footers
RegisterHeader() · RegisterFooter()
.Save()write to disk
.GetBytes()raw []byte
.GetBase64()inline / API responses
.Merge()combine documents
+ HTML fragmentsmix inside the grid
Layout model

Rows and columns on a 12-column grid.

The same mental model as the web — but resolved to exact points on the page. Spans add up to twelve; Paper measures, positions, and paginates.

DOCUMENT GRID12 COLUMNS
Header — col 12
col 4
col 4
col 4 · QR
Table — col 8
Totals — col 4

Explicit, by design.

01
Rows hold columns.

Each row opens a 12-unit track. Add columns with a span and Paper handles the math.

02
Columns hold components.

Any component — or a nested row — drops into a column. Composition all the way down.

03
Deterministic pagination.

Content that overflows the page flows predictably to the next, headers and footers intact.

HTML pipeline

HTML in. Structured PDF out.

Paper parses your markup, resolves it into the same component tree the grid API produces, then renders to an exact, paginated PDF.

INPUTHTML
invoice.html
<section class="invoice">
  <h1>Invoice</h1>
  <table>
    <tr><td>API</td>
    <td>$480</td></tr>
  </table>
  <img src="qr.png" />
</section>
PARSE · RESOLVE · RENDER
OUTPUTPDF
Invoice
A4 · 595×842pt · 1 page
TOTAL DUE$840.00
Testing & metrics

Inspect the tree. Assert the output.

Because every document is a component tree, you can unit-test structure without rendering a single pixel — then watch generation behavior with optional metrics.

m.GetStructure() — deterministic snapshot
Document a4 · portrait ├─ Header │ └─ Row [12] ├─ Row [8,4] │ ├─ Text "Invoice" │ └─ QRCode 88×88 ├─ Table 3 rows └─ Footer PageNumber
doc.GetReport() — last run
18 ms
Generation time
7
Components
1
Pages
42 kb
Output size
Throughput · docs/sec
1,240
Use cases

Built for the documents your service ships.

Anywhere you generate paper, on demand, at volume.

Ship documents that
render exactly right.

Add Paper to your Go service and generate production PDFs in a single import.

$ go get github.com/avdoseferovic/paper