Stop Splitting Atoms • The Applied Go Weekly Newsletter 2025-06-01
Your weekly source of Go news, tips, and projects
Stop Splitting Atoms
Hi ,
Have you used the sync/atomic
package yet? Yes, this low-level synchronization package whose documentation recommends using channels or the sync
package instead. But sometimes, the atomic
package is exactly the one you need, and you happily open the docs... and stumble over an unexpected warning in each package-level function's documentation. Why is that? Check out this week's Spotlight to discover the reasons.
But first, learn more about synctest
, DI frameworks, and Green Tea.
Have a great week ahead!
–Christoph
Featured articles
Go synctest: Solving Flaky Tests
Phuong Le explains how the new (experimental) synctext
package addresses flaky concurrent tests by creating isolated environments with synthetic time and controlled goroutine execution.
You probably don't need a DI framework | Redowan's Reflections
No, you probably don't need a DI framework for your Go project. Dependency injection in Go is dead easy and can be done in a few, highly readable lines of code.
The purpose of knowledge is action.
This is a three-part series on memory layout and the upcoming Green Tee garbage collector, and as these three parts are all there is on this new blog, I've linked to the blog's hompage.
Podcast corner
Cup o' Go: 🌁 Live from San Francisco, it's Cup o' Go! Elastic, Green Tea, and LLM toolboxes
Another episode of Cup o' Go, with a bucket full of topics brought to you by Jonathan and Shay.
Fallthrough: Event Driven Architectures
Event-driven architecture promises more robustness, easier deployment, and a reduced risk of bottlenecks than classic approaches to architecting distributed systems. Fallthrough's Angelica talks to Indu Alagarsamy, Ignacio Castillejos, and Chris Richardson to find out if these claims hold.
Spotlight: Atomic functions or methods?
Channels and mutexes cover most of your code's synchronization needs. You'd rarely have to reach for the sync/atomic
package, but if you have to, you may notice the recommendation that comes with each package-level atomic function such as AddInt32
:
"Consider using the more ergonomic and less error-prone Int32.Add instead."
Uh, but why? Both the package-level function and the atomic type's method do exactly the same, right? Right, but they do it in different ways. The documentation says "more ergonomic and less error-prone". Sounds good, but what does that mean?
Atomic types and their methods are more ergonomic
The case for ergonomics is clear to see if you compare the two approaches directly:
// Package-level function (less ergonomic)
var counter int32
atomic.AddInt32(&counter, 1)
// Type-specific method (more ergonomic)
var counter atomic.Int32
counter.Add(1)
The method is, very obviously, shorter to type, hence less wordy. For the package-level function, you have to repeat the counter's type in the function name and have to remember that the counter parameter is a pointer that you must dereference. The method, on the other hand, exposes a clear and brief Add()
method.
Atomic types and their methods are less error-prone
This one is less obvious than the ergonomics, but if you look closely, you notice that the "atomic" counter in the package-level function example isn't atomic at all; it's a plain int32
. Imagine a new developer on the team who fixes a critical bug in a hurry and increments the counter through counter++
. This increment operator isn't atomic, and now your code has a data race condition.
This cannot happen with atomic types like atomic.Int32
, as the increment operator isn't defined on them. The only way to increment an atomic Int32
is by calling Add(1)
.
var counter atomic.Int32
// This won't even compile
counter++
// This works
counter.Add(1)
So: Use the atomic types and their methods instead of the package-level functions. It's not just a matter of taste.
Quote of the Week: Go's core promise
Go's core premise is that developer tools should prioritize scale from the start.
More articles, videos, talks
Coding a database proxy for fun - YouTube
Alex Pliutau stumbled upon a SQL DB proxy the Figma team uses as part of their DB infrastructure. He got curious and turned his curiosity into code.
let's build a Garbage Collector (GC) from scratch
If you want to truly learn how a GC works, build your own from scratch! That's what Venkat did. And not only that, but he also wrote down all the details.
What's new in Go - YouTube
Cameron Balahan, product lead for Go at Google, and Marc Dougherty, head of developer relations for Go, present Go’s three core principles: productivity, complete developer experience, and production readiness, cover additions and improvements in Go 1.23 and 1.24, and discuss its growing role in AI infrastructure.
JSON Web Tokens in Go - by Alex Pliutau - packagemain.tech
All you need to get started with using JSON Web Tokens (JWT) in Go.
Building scalable multi-tenant applications in Go | Atlas | Manage your database schema as code
An app with multiple users needs to take extra care of data and process isolation in various places. Rotem Tamir shows how to use Ent's privacy rules, Postgres row-level security, and per-user schemas to achieve robust isolation.
Taking more control over your Cobra CLI documentation · Jamie Tanna | Software Engineer
Jamie Tanna found that Cobra's documentation generation didn't meet his needs, so he set out to fix it.
htmx and templ
You can serve static web pages easily with a few lines of Go. For serving dynamic content, the standard answer is, "JavaScript". Eeek!
Or you use HTMX instead.
How To Build Your Own MCP Vibe Coding Server in Go Using GoMCP | by Alma Tuck | May, 2025 | Medium
Alma Tuck built an MCP library for Go and shows you the steps to build a Model Context Protocol (MCP) server that provides useful tools to LLMs for working with codebases.
Sad story of http.DefaultTransport
Why DefaultTransport
is a leaky abstraction, and how this could be fixed.
Projects
Libraries
GitHub - jetify-com/sse: Server-Sent Events for Go. A tiny, dependency-free, spec-compliant library compatible with the HTTP stdlib.
The HTTP protocol was designed for simple one-way communication: A client sends a request and gets an answer from the server. With Server-Side Events (SSE), HTTP servers can send requests to clients, which is useful for pushing new data to a client without having the client poll for updates. SSE got an increase in popularity recently as one of the protocol options for MCP servers. jetify-com/sse
is a small, dependency-free SSE library for Go.
GitHub - ploMP4/chafa-go: Go bindings for the Chafa terminal graphics library. Render images on the terminal without CGO or external dependencies.
If you want to render images in a terminal, AND don't want to rely on some modern terminals' ability to render high-res images, AND want to have lots of knobs to turn (dithering, color space, and more), AND want a pure-Go library for that (ie, no CGO), then chafa-go
is for you.
Tools and applications
GitHub - zix99/rare: Create terminal-based histograms, bar graphs, tables, heatmaps and more in realtime using regex and expressions.
Scan data in text files and turn it into histograms, heat maps, and other visualizations—right in the terminal.
GitHub - LissaGreense/GO4SQL: SQL engine written in golang
A pure-Go, in-memory SQL engine, written as a side project.
GitHub - yarlson/lnk: 🔗 Git-native dotfiles management that doesn't suck.
If you want to share your dotfiles between machines but tools like chezmoi
feel too complex to use, try lnk
. All it does is to move your dotfiles to ~/.config/lnk
and create symlinks in their original locations. It even wraps git commands so you don't have to switch tools.
@oppi.li/gust at main · tangled
gust
is like the well-known air
but with a TUI for live output and error highlighting.
GitHub - lyeslabs/mcpgen: Generate Go MCP server boilerplate from OpenAPI 3 specifications
You have a Go service with an OpenAPI spec? Great, now you have an MCP server!
GitHub - Wissance/Ferrum: Simple and Fast OpenId-Connect authorization server with Keycloak compatible API written in GO. The possibility to increase application clients number and authentication/authorization speed without any modification due to the API compatibility
Ferrum aims to be a minimalistic alternative to Ory Hydra and Keycloak.
GitHub - buarki/viztruct: Struct padding visualizer
Whether an app is memory-intense or the available memory is tiny, you might end up having to optimize the memory layout of structs. viztruct
is a CLI tool and a web app that helps you with this task by visualizing paddings and optimizing your struct layout automatically.
Completely unrelated to Go
Common abstraction traps
A very concrete post about how to fall prey to the wrong kind of abstraction. By Swizec Teller.

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.
Christoph Berger IT Products and Services
Dachauer Straße 29
Bergkirchen
Germany