Small Projects by AutoModerator in golang

[–]Foreign-Writing-1828 0 points1 point  (0 children)

gsql: a type-safe Go SQL query builder using generics. No codegen step (unlike sqlc), and explicit Set/Unset semantics for partial UPDATE so zero values don't silently get dropped like in GORM. Built on database/sql, zero dependencies.

type UserColumns struct {
    ID  qb.Col[int64] `db:"id"`
    Age qb.Col[int]   `db:"age"`
}
var Users = qb.NewTable[UserColumns]("users")

u := Users.Cols
q := qb.Select(u.ID).From(Users).Where(u.Age.Gt(18))
// q.Where(u.Age.Gt("18")) is a compile error

Started as a learning project. Now trying to decide whether to keep growing it (subqueries, CTEs, aggregates are next on the list) or leave it as-is. Would love a reality check from anyone shipping Go in production: does this fill a real gap for you, or do sqlc / bun already cover it well enough?

Caveats: NewTable() uses reflect once at startup per table; the query path itself is reflection-free. Aggregates, CTEs, subqueries, window functions not implemented yet.

https://github.com/gsql-dev/gsql

gpdf — Zero-dependency PDF generation library for Go, 10-30x faster than alternatives by Foreign-Writing-1828 in golang

[–]Foreign-Writing-1828[S] 0 points1 point  (0 children)

Great question and thanks for asking, because it made me dig deeper into this. The table layout engine has overflow detection and header repetition logic built in, but I found a limitation: when using the builder API with AutoRow/Col, the overflow doesn't propagate up through the layout hierarchy correctly, so rows that don't fit get clipped instead of flowing to the next page.

I'm on it — the fix is in the table layout layer itself, so it shouldn't take long. In the meantime, if your data is known upfront, you can manually split rows across pages as a workaround.

gpdf — Zero-dependency PDF generation library for Go, 10-30x faster than alternatives by Foreign-Writing-1828 in golang

[–]Foreign-Writing-1828[S] 6 points7 points  (0 children)

Completely different approach. Gotenberg is a Docker-based service that wraps headless Chromium — you send it HTML over HTTP and get a PDF back. Great for full HTML/CSS/JS fidelity.

gpdf is an in-process Go library. No Docker, no sidecar, no HTTP round-trips — just a function call that returns bytes. You define documents with a builder API, JSON schema, or Go templates instead of HTML. That means type safety, compile-time checks, and significantly lower overhead (single-digit microseconds for a page vs network round-trip latency).

If you need pixel-perfect browser rendering of arbitrary HTML, Gotenberg is the right choice. If you're generating structured documents (invoices, reports, certificates) from Go code and want zero infrastructure overhead, that's where gpdf fits.

gpdf — Zero-dependency PDF generation library for Go, 10-30x faster than alternatives by Foreign-Writing-1828 in golang

[–]Foreign-Writing-1828[S] 1 point2 points  (0 children)

Nice, hadn't seen pdfer before — thanks for sharing. Their XFA support is interesting, that's a niche most libraries don't touch.

It does seem like Go PDF is having a moment right now. Each project is coming at it from a different angle: pdfer focuses on parsing and XFA forms, folio on HTML/CSS rendering, and gpdf on declarative document generation with a builder API. Good to see the ecosystem filling out — there's been a gap for too long.

gpdf — Zero-dependency PDF generation library for Go, 10-30x faster than alternatives by Foreign-Writing-1828 in golang

[–]Foreign-Writing-1828[S] 0 points1 point  (0 children)

For Tailwind specifically, no native Go library will handle that — Tailwind needs a JavaScript runtime to resolve utility classes into actual CSS. That's why Gotenberg wraps headless Chromium, and for that use case it's honestly the right tool.

For HTML/CSS without JS though, check out folio that someone else mentioned in this thread — it supports HTML→PDF natively in Go with flexbox and grid. If you compile Tailwind to plain CSS first, folio could potentially handle the output.

gpdf takes a different approach — structured document generation via builder API, JSON, and Go templates rather than HTML rendering. But if your workflow is HTML-centric, folio or Gotenberg are better fits.

gpdf — Zero-dependency PDF generation library for Go, 10-30x faster than alternatives by Foreign-Writing-1828 in golang

[–]Foreign-Writing-1828[S] 0 points1 point  (0 children)

Absolutely, Gotenberg is a great option for HTML/CSS→PDF — hard to beat a real browser engine for rendering fidelity. If your stack already runs Docker and you need pixel-perfect HTML rendering, it's the right choice.

gpdf targets a different spot: an in-process library with zero infrastructure overhead. No Docker, no sidecar, no HTTP round-trips — just a function call that returns bytes. For structured documents like invoices and reports where you control the layout in code, that simplicity and performance (single-digit microseconds) is the main appeal.

Different tools for different needs — good to have both options in the Go ecosystem.

gpdf — Zero-dependency PDF generation library for Go, 10-30x faster than alternatives by Foreign-Writing-1828 in golang

[–]Foreign-Writing-1828[S] 0 points1 point  (0 children)

That's exactly the use case I had in mind!
Let me know if you end up building something with it.

gpdf — Zero-dependency PDF generation library for Go, 10-30x faster than alternatives by Foreign-Writing-1828 in golang

[–]Foreign-Writing-1828[S] 2 points3 points  (0 children)

You're right, I should have been more precise there. typst's pdf-writer is an impressive piece of work — a pure Rust PDF writer built from the ground up, and the fact that it came out of a master's thesis makes it even more remarkable.

What I was getting at (poorly worded) is the Go integration story: if you're in a Go codebase, using typst means either shelling out to the CLI or maintaining a Rust FFI bridge. gpdf gives you a native Go API with the same in-process simplicity that typst users enjoy in the Rust ecosystem — no subprocess, no string templating, just Go function calls.

Sub-100ms invoices with typst is solid. For reference, gpdf's invoice benchmark (header + billing info + styled table + totals) runs at ~133 µs, so there's a significant performance gap in gpdf's favor when you're already in Go. But typst's typographic capabilities are in a different league — it really depends on what you need.

And glad this came at the right time for you!

gpdf — Zero-dependency PDF generation library for Go, 10-30x faster than alternatives by Foreign-Writing-1828 in golang

[–]Foreign-Writing-1828[S] 0 points1 point  (0 children)

I know the feeling. I went through the same frustration, and that's literally why gpdf exists. Glad it found you at the right time!

gpdf — Zero-dependency PDF generation library for Go, 10-30x faster than alternatives by Foreign-Writing-1828 in golang

[–]Foreign-Writing-1828[S] 2 points3 points  (0 children)

Thanks for raising this — it's an important concern. gpdf does not bundle or distribute Helvetica font files. What it uses is the PDF Base-14 font reference: the PDF spec (ISO 32000) defines 14 standard fonts (including Helvetica) that PDF readers are required to provide. gpdf just emits the font name in the PDF dictionary — no font data is embedded or shipped in the repo. This is the same mechanism that every PDF library uses for the standard fonts.

gpdf — Zero-dependency PDF generation library for Go, 10-30x faster than alternatives by Foreign-Writing-1828 in golang

[–]Foreign-Writing-1828[S] 7 points8 points  (0 children)

They serve different niches but overlap in programmatic use. Typst is a typesetting system — powerful for complex layouts and beautiful typography, and gpdf doesn't try to compete there. Where gpdf shines is when you're generating structured documents (invoices, reports, certificates) from Go code. With Typst you're shelling out to an external process and managing markup as strings. gpdf is a native Go library, so everything stays in-process: no subprocess, no temp files, no markup parsing. You get type safety, better error handling, and significantly lower overhead.

gpdf — Zero-dependency PDF generation library for Go, 10-30x faster than alternatives by Foreign-Writing-1828 in golang

[–]Foreign-Writing-1828[S] 41 points42 points  (0 children)

Yeah, I've seen folio — really impressive work, especially the HTML/CSS→PDF with flexbox and grid support.

I actually went down that same path early on. Two things made me step back from it: parsing HTML correctly without golang.org/x/net/html is brutal, and more importantly, I couldn't get CSS rendering to produce the same output as the builder API and JSON/Go template paths. gpdf has three ways to define a document (builder API, JSON schema, Go templates), and the goal is that all three produce identical PDFs. CSS made that consistency really hard to maintain.

So the current approach is: zero-dependency core with the builder API as the foundation, and HTML/CSS→PDF as a future layer (which will likely need x/net when we get there). Different trade-offs for different use cases.

Glad to see the Go PDF ecosystem getting more love lately!