The Go Engineer’s Toolbox: Daily Tools from Two Seasoned Gophers

From Podman to Caddy, from USQL to AI coding — two senior Go engineers get honest about what they actually use.

分享
The Go Engineer’s Toolbox: Daily Tools from Two Seasoned Gophers
Gemini

Have you ever noticed something interesting? Two Go engineers on the same team can start their mornings in completely different ways. One is waiting for docker-compose up the containers to spin up. The other already has its service running with go run.

Your tool choices reveal more about your personality and values than your technology stack ever could.

I recently listened to Episode 72 of the Go Podcast, where hosts Dominic St-Pierre (a developer since 2001) and Morten Vistisen (a full-stack contract developer) spent over an hour discussing the tools they use every day. What made it compelling was that they disagreed on almost everything — and those disagreements were the most valuable parts.

Here’s what they discussed, with my own take layered in.

Containers: Podman vs. “I Just Won’t Install Docker”

This was the most heated debate in the whole episode.

Dominic is a committed Podman advocate. His argument is straightforward:

“Podman doesn’t need root privileges. It runs entirely in user space. That brings a lot of benefits for me.”

Podman’s biggest selling point over Docker is that it’s rootless — no daemon, no privileged mode, and a CLI that’s nearly identical to Docker. If you’ve ever been frustrated by Docker Desktop’s licensing changes, its resource consumption, or its root requirements, Podman is worth a serious look:

# Podman commands are almost fully compatible with Docker 
podman run -d --name pg -p 5432:5432 -e POSTGRES_PASSWORD=dev postgres:latest 
podman run -d --name redis -p 6379:6379 valkey/valkey:latest

Morten’s position was completely different. He prefers installing dependencies directly on his local machine:

“The promise of containerized dev environments is great, but the actual experience is always so much slower than just running things natively.”

Dominic pushed back immediately: “But if you need Valkey, Redis, Postgres, and a bunch of other services, you don’t really want all of that installed locally, do you?”

To his credit, Morten was honest — he’s created plenty of Docker Compose files to set up dev environments for teams. But for his personal workflow, he prefers to know exactly where everything lives and manage it himself.

My take: This is a collision between two engineering philosophies. Dominic optimizes for environment consistency and isolation. Morten optimizes for performance and control. Neither is wrong. It depends entirely on your context — if you’re on a multi-person team, containerization is almost non-negotiable; if you’re a solo developer, native installs are perfectly reasonable.

Caddy: The Underrated Go Infrastructure Tool

This was the one topic where both hosts were in complete agreement — and both were enthusiastic.

Caddy is a web server and reverse proxy written in Go. Automatic HTTPS is its signature feature. But Dominic brought up something even more impressive — on-demand SSL certificate generation:

“You can have Caddy accept all incoming traffic. If a domain doesn’t have an SSL cert yet, it calls an API you specify, gets back a list of allowed domains, and automatically generates the certificate. That feature blew my mind.”

For multi-tenant SaaS architectures, this is a game-changer. Imagine every customer having their own custom domain, and you never manually touch a single certificate. Caddy handles it automatically.

Morten’s use case was slightly different. He primarily uses Caddy’s Admin API to dynamically register domains without restarting or touching config files:

# Dynamically add a route via Caddy Admin API (no restart needed) 
curl localhost:2019/config/apps/http/servers/srv0/routes \ 
-X POST \ 
-H "Content-Type: application/json" \ 
-d '{ 
"match": [{"host": ["newclient.example.com"]}], 
"handle": [{"handler": "reverse_proxy", "upstreams": [{"dial": "localhost:8080"}]}] 
}'

Compared to Nginx’s config file hell or Traefik’s labeling complexity, Caddy’s simplicity is genuinely striking. And since it’s written in Go — if you need custom behavior, you just write a Go plugin.

Database Tools: Stay in the Terminal

Morten is a heavy terminal user, and he recommended two database tools worth knowing about.

USQL — One CLI to Rule Them All

USQL is a universal database CLI written in Go. It supports PostgreSQL, MySQL, SQLite, SQL Server, and nearly every other mainstream database, with a unified command syntax across all of them:

# Connect to different databases with the same commands 
usql postgres://localhost/mydb 
usql mysql://root@localhost/mydb 
usql sqlite:///path/to/db.sqlite 
# Use \dt to list tables in any database (familiar if you know psql) 
\dt
“I don’t have to switch between psql and the MySQL CLI anymore. It’s like a thin wrapper around psql, but it works with everything.”

DBLab — A TUI Database Client

If you want something more visual than a raw CLI but still don’t want to leave your terminal, DBLab offers a TUI (terminal user interface) experience.

That said, Morten admitted that in production environments, he still reaches for DBeaver — because a proper GUI client has better guardrails against accidental destructive operations.

Dominic also brought up SQLite, with genuine admiration for its design. As an embedded database, SQLite’s code quality and test coverage are legendary in the software engineering world. If you haven’t added SQLite to your toolkit — whether for data analysis, local caching, or embedded storage — I’d strongly encourage you to take a serious look.

AI-Assisted Development: $20/Month as a Discipline Mechanism

AI coding is the hottest topic in the industry right now, and both hosts were refreshingly pragmatic about it — they use it, but with boundaries.

Morten subscribes to both Anthropic and OpenAI’s $20/month plans. He said something I found genuinely interesting:

“The quota is just about enough. Not always enough, but that forces me to stay in a middle ground — I’m still writing code myself, and I’m still carefully reviewing what the AI produces.”

The $20 limit accidentally became a self-discipline mechanism. Because tokens are finite, you’re forced to think about what’s actually worth delegating to AI and what you should write yourself.

Dominic’s usage skews more toward non-coding tasks. He had Claude review the marketing website for one of his open source projects:

“I gave it a lot of context, then said: give me an honest review. And it roasted me. But that kind of feedback — no emotions, purely technical — was genuinely valuable.”

On Go code generation specifically, both hosts were surprisingly conservative:

  • Dominic doesn’t let AI write his Go code (he’s not satisfied with the output quality), but he hands off frontend and React work to AI without hesitation.
  • Morten treats AI as a brainstorming partner and a migration tool. Architecture decisions stay with him.

Morten made a point that I think is genuinely profound:

“If you use AI to write code faster, you have to accept that the code will be sloppier. You can’t have it both ways.”

They also mentioned a sobering real-world case: an AI-assisted development project that led to millions of driver’s license records being leaked through an insecure S3 bucket. AI can help you write code. But the responsibility for security review never leaves your hands.

Deployment Philosophy: Docker or Bare Metal?

On deployment, the two hosts once again showed very different instincts.

Morten deploys his SaaS product directly on bare metal via systemd — compile the binary, write a systemd service, done. Simple and direct, though zero-downtime deployments are challenging.

# A typical systemd config for a Go service 
[Unit] 
Description=My Go API Server 
After=network.target 
[Service] 
Type=simple 
ExecStart=/opt/myapp/server 
Restart=always 
RestartSec=5 
[Install] 
WantedBy=multi-user.target

If you go with Docker + Traefik, zero-downtime deployments are free — Traefik detects new containers and seamlessly switches traffic. But for small-scale operations, Dominic’s attitude is refreshingly honest: if it’s down for a few seconds, who actually cares?

This reminds me of a principle I keep coming back to: don’t introduce complexity to solve problems you don’t have. Kubernetes is powerful. But if your service runs on one machine, systemd is enough.

Go Ecosystem Tools Worth Watching

The podcast touched on a few other tools worth putting on your radar:

The Tools They Want to Build But Haven’t Yet

Near the end, both hosts talked about tools they want to build, which I think is just as revealing as the tools they already use.

Dominic wants to build a CLI email client. Not a TUI — a real command-line tool. One that drops you back to the shell prompt after each action, uses IMAP/SMTP, and displays email lists as plain-text tables.

Morten wants to build a video transcription and auto-editing tool that uses Whisper for speech recognition to automatically cut out silent sections from videos. He mentioned that YouTube creator Dreams of Code has already built something similar in Rust.

Both ideas share a common thread: using Go’s CLI ecosystem to eliminate friction from everyday workflows. And that might be where Go excels most — fast compilation, single binary output, cross-platform support. It’s a natural fit for CLI tooling.

Closing Thoughts

What stuck with me most from this episode wasn’t any specific tool recommendation. It was the pragmatic mindset both engineers brought to their choices:

  1. Tools serve your workflow, not the other way around. Morten doesn’t use Docker for local dev — not because he can’t, but because native installs are faster for him.
  2. Constraints create discipline. A $20 AI subscription limit actually helps maintain good code review habits.
  3. Default to simple. If systemd is enough, don’t reach for Kubernetes. If a few seconds of downtime is acceptable, don’t build zero-downtime infrastructure.
  4. Prioritize tools written in languages you know. Caddy, Traefik, USQL, Crush — when something breaks, you can actually read the source code.
  5. AI is a tool, not a replacement. Use it for tedious migrations and as a reviewer. Keep architecture decisions and security reviews firmly in human hands.
The best tool isn’t the one with the most features. It’s the one with the least friction.

References

This article is based on Go Podcast Episode 072, with added commentary and context from the author. If you’re interested in the Go developer toolchain, I’d recommend listening to the original episode for the full discussion.