The Applied Go Weekly Newsletter logo

The Applied Go Weekly Newsletter

Subscribe
Archives
June 22, 2025

Go Before You Wait • The Applied Go Weekly Newsletter 2025-06-22

AppliedGoNewsletterHeader640.png

Your weekly source of Go news, tips, and projects

2025-06-22 Newsletter Badge.png

Go Before You Wait

Hi ,

The smallest improvements are sometimes the best, as in the sync package that receives a new WaitGroup method in Go 1.25. The new Go() method isn't just small at the surface, it's implemented in a handful of lines of code.

Small is beautiful, don't you think, too?

–Christoph

Featured articles

The Small Change That Made a Big Impact - Compa Compila

When your code is slow and the main logic is not the culprit...

Writing Load Balancer From Scratch In 250 Line of Code

The best option for learning how a load balancer works is to implement one. The second-best option is to read an article that explains how the author implemented a load balancer.

Gist of Go: Race conditions

Races are only fun if humans, animals (rats excluded(*)), or vehicles are involved. They cease to be fun if goroutines get into a race on accessing data. Luckily, the book Gist of Go (a work in progress) got a chapter about race conditions.

(*) Why? Because if you win a rat race, you're still a rat.

Podcast corner

Cup o' Go: Agentic workflows and AI firewalls, so pretty much cancelling ourselves out

Listen closely—don't the voices of Jonathan and Shay sound AI-generated?

Well ... probably not.

Fallthrough: Go's Error Handling Is Handled

A recent Go Blog post made it clear: Go's error handling remains as it is. Kris, Ian, and Matt think it's fine, and so do I, and so do you?

Spotlight: New in Go 1.25: WaitGroup.Go()

This is an improvement many of you will love. It is a usability enhancement along the lines of testing's b.Loop() that did away with a clumsy loop condition (and made benchmarking more efficient) in Go 1.24.

I'm talking about WaitGroup.Go(). Starting with Go 1.25, you no longer need to call Add(1) for each goroutine spawned inside a WaitGroup and hope that there's no mismatch with the number of calls to Done().

With Go 1.25, using a WaitGroup is as easy as:

var wg sync.WaitGroup

for i := 0; i < 3; i++ {
    wg.Go(func() {
    // do something 
    })
}

wg.Wait()

(Playground link)

How is Go() implemented? This is easy to find out, and that's one of the many bits that I love about Go: In the documentation of a Go package on pkg.go.dev, you can click on the title of any identifier (function, type, etc.) to open its source code in Go's official repository. If you drill down on the Go() method, you'll discover that the implementation of WaitGroup.Go() is refreshingly simple; it's just a thin wrapper over the "old" style:

func (wg *WaitGroup) Go(f func()) {
    wg.Add(1)
    go func() {
        defer wg.Done()
        f()
    }()
}

Go() simply does the Add()/Done() bookkeeping under the hood for you. Neat!

Quote of the Week: The proof is in the pudding user

Go change the way of thinking and the proof is the people who are using Go or people who are just switched from other languages like me. No language is perfect but Go is closest to perfect.

–Abrar Mirje

More articles, videos, talks

OpenTelemetry for Go: measuring the overhead | Coroot

OpenTelemetry enables a server to collect and submit metrics, logs, and traces—but what is the cost? Nikolay Sivko measured the performance overhead of OpenTelemetry in a high-load Go application.

Parsing, Not Guessing | Francis Sunday

Regular expressions are powerful but frequently overused. They become complex very quickly and then are a royal PITA to debug. (Hint: sites such as regex101.com are your friend.) Markdown is a good example of a language that shouldn't be "parsed" with regular expressions. It's much better to parse a Markdown text into an abstract syntax tree (AST). Francis Sunday demonstrates how the goldmark package exposes an AST of a rendered Markdown text that can be easily traversed for rendering purposes.

The joy of (type) sets — Bitfield Consulting

With the introduction of type parameters in Go 1.18, interfaces were no longer just "lists of functions" but expanded into a means of constraining the set of allowed types for a type parameter. John Arundel explores the possibilities.

Introducing Chess V2: A New Chess Library in Golang

Uh—what does a chess library do? Specifically, brighamskarda/chess? It can generate legal and pseudo-legal moves from a given board status, parse positions in FEN notation, parse moves in SAN or UCI format, check positions for checkmate or stalemate, and then some.

Statically and dynamically linked Go binaries - YouTube

Go binaries are statically linked, until they aren't. Alex Pliutau explores the differences.

Optimizing calling Windows DLL functions in Go

If you need to call functions in Windows DLLs, you'd go with sys/windows ... unless there is a smarter way.

Unexpected security footguns in Go's parsers

When reading this article, keep this comment from Jeremy Bowers in mind:

"There's a lot of good information in there but I find the tone alarmist. Much of that is user error with plenty of analog in basically every other language. Variations in JSON parsing are everywhere, there is not One True Standard that if you deviate from it you are presumptively In Violation and can be blamed. There's just too much variation for that. JSON issues in a lot of other languages abound, and some are just endemic to the format. The real problem is just that these standards are not as safe as their ease-of-use may imply."

Projects

Libraries

GitHub - floatdrop/debounce: A zero-allocation debouncer written in Go.

"Call this function, but don't call it too often!" This debouncer delays a function call until the function hasn't been called in a specified time and then runs it; all prior calls get dropped. Debouncing can be useful for rate limiting and reducing redundant calls of functions.

GitHub - nlpodyssey/openai-agents-go: A lightweight, powerful framework for multi-agent workflows in Go

The OpenAI Agents SDK is for Pythonistas only, but here is a port for Gophers!

GitHub - john-marinelli/panes: A Bubble Tea component for creating multi-pane applications

A multi-pane application in your terminal? No problem with Bubble Tea and john-marinelli/panes.

GitHub - charmbracelet/fang: The CLI starter kit

There is virtually no way around the Charm packages for developing terminal UI (TUI) apps. Now Charm has a new (still experimental) package: Fang, a layer on top of Cobra that aims to make starting a CLI app even easier.

Tools and applications

GitHub - firstrow/mcwig

Vim in Go? For a toy project, McWig has quite a few features already, including "lots of bugs". The author plans to develop this proof of concept into a full editor.

GitHub - yokecd/yoke: Kubernetes Package Management as Code; infrastructure as code, but actually.

Sick of templating yaml with yaml for Kubernetes package management? With Yoke, you can write resource description in the language you love—which is probably Go, but any language that compiles to WASM should do.

GitHub - goptics/vizb: An interactive go benchmarks visualizer

How do you turn benchmark outputs into interactive HTML charts? With a single command.

Go Struct Analyzer

Optimizing struct memory usage has become easier. Go Struct Analyzer is a VSCode package (also available on Open-VSX) for uses of VSCodium and other VSCode derivates) that augments struct fields with their sizes, and alerts the user about optimization opportunities.

Completely unrelated to Go

Reinvent the Wheel

Don't reinvent the wheel—or rather, do! Matthias Endler knows why reinventing things is actually quite good for everyone.

Rolling the ladder up behind us

With LLMs reaching the level of a junior developer, companies may be tempted to stop hiring juniors as the LLM do the same stuff but cheaper. Xe Iaso explains why this is a footgun.

Happy coding! ʕ◔ϖ◔ʔ

Questions or feedback? Drop me a line. I'd love to hear from you.

Best from Munich, Christoph

Not a subscriber yet?

If you read this newsletter issue online, or if someone forwarded the newsletter to you, subscribe for regular updates to get every new issue earlier than the online version, and more reliable than an occasional forwarding. 

Find the subscription form at the end of this page.

How I can help

If you're looking for more useful content around Go, here are some ways I can help you become a better Gopher (or a Gopher at all):

On AppliedGo.net, I blog about Go projects, algorithms and data structures in Go, and other fun stuff.

Or visit the AppliedGo.com blog and learn about language specifics, Go updates, and programming-related stuff. 

My AppliedGo YouTube channel hosts quick tip and crash course videos that help you get more productive and creative with Go.

Enroll in my Go course for developers that stands out for its intense use of animated graphics for explaining abstract concepts in an intuitive way. Numerous short and concise lectures allow you to schedule your learning flow as you like.

Check it out.


Christoph Berger IT Products and Services
Dachauer Straße 29
Bergkirchen
Germany

Don't miss what's next. Subscribe to The Applied Go Weekly Newsletter:
LinkedIn
Powered by Buttondown, the easiest way to start and grow your newsletter.