Golang
Go Project Structure: Patterns That Scale
Practical guide to structuring Go projects from flat layouts to hexagonal architecture, with examples for CLIs, APIs, and monorepos
Go doesn’t enforce a project layout. That freedom is powerful but requires discipline — start simple and let structure emerge as complexity grows.
Using Go Modules Hosted in a Private GitLab Repository
Configure Go, GitLab CI job tokens, and .netrc to seamlessly consume private Go modules from internal GitLab repositories
When your Go project depends on an internal library living in a private GitLab repository, a plain go get will fail — GitLab doesn’t know who is asking, and Go doesn’t know the repository is private. Fortunately, a handful of configuration steps sorts everything out, both locally and in CI.
perplexity-go: a Go library for the Perplexity API
A lightweight, idiomatic Go client for Perplexity AI — chat completions, the Search API, and a few notes from the maintainer
I’ve been maintaining perplexity-go for a while now — a small Go client for the Perplexity AI API. It started as scratching my own itch (I needed a CLI to query Perplexity from scripts) and grew into a library I now reach for whenever a Go project needs real-time, cited answers from the web.
This post is a tour of what it does, why it exists, and how to use it.
A curated list of Go libraries I use or plan to evaluate — covering resilience, web, SQL, concurrency, terminal UIs, testing, and more
A running list of Go modules I use or want to keep on my radar. Some I reach for daily, others I’m still evaluating. The Go ecosystem moves fast, so this post will keep evolving — treat it as a snapshot, not a manifesto.
Go: Handling time.Now() in Tests
Forget time-mocking libraries — a single function field on your struct is all you need to make time deterministic in Go tests
Time-dependent code is one of the classic pain points in unit testing. A function that calls time.Now() produces a different value every run, and assertions become a moving target. There are popular packages to solve this — but you don’t actually need any of them. A few lines of plain Go are enough.