You needed one folder. Git wanted 2.6 GB.
gitsnip v0.2: paste a folder link, get just that folder.
Next.js's with-docker example: 17 files in 4.8s.
GitHub, GitLab, Codeberg, sourcehut, SSH. Single files, globs, --json.
https://t.co/TcJZY8Fznv
If you're learning Go, learn the standard library first, especially net/http.
If you need a library suggestion to begin with:
- add a small router like Chi only when you feel "friction".
- avoid heavy frameworks like Gin until you clearly need their features.
- prefer raw SQL with tools like sqlc over big ORMs like GORM.
If you need a TODO list right now, then
- start with net/http and build everything yourself once.
- write handlers using http.HandlerFunc.
- register routes with ServeMux.
- add middleware by wrapping handlers.
- parse JSON manually with json.Decoder.
- handle errors explicitly (fmt.Errorf).
- do logging yourself (global logger).
- implement a graceful shutdown strategy (e.g., https://t.co/49o7msXfRp)
This helps us understand request lifecycle, context propagation, cancellation, response writing, etc.
After this, every framework becomes just a thin wrapper. Without this knowledge, frameworks feel magical and become hard to debug
If you find yourself repeating boilerplate across projects, that is the indicator (signal) to introduce a library. Not before.
---
When you need routing ergonomics, add Chi. It stays close to http.Handler and does not hide anything.
You still pass http.Request and http.ResponseWriter Migration cost is near zero, and you can remove it later. This keeps lock-in low and keeps your mental model simple.
Avoid heavy frameworks early.
Gin adds its own:
- context type,
- error flow,
- binding system.
That couples your app to their APIs. Refactoring out later is quite painful. If you do not truly need automatic binding, validation chains, or their middleware ecosystem, it is extra surface area with little benefit.
---
For databases,
- avoid ORMs first.
- use database/sql directly.
- write SQL yourself.
- use prepared statements.
- map rows into structs manually.
- if you want safety and less boilerplate, use sqlc to generate typed Go code from SQL.
This keeps SQL visible, debuggable, and portable. ORMs often hide queries, create unexpected joins, and break on version changes. Many people were burned by this.
Dependency rule that most of us converge on:
"Use stdlib until it blocks you. Then add the smallest possible dependency. Prefer small, focused libraries over full stacks."
Your Golang knowledge, explaining:
Goroutines
Channels
Context cancellation
WaitGroups
Mutex vs RWMutex
Buffered vs unbuffered channels
Worker pools
Select statements
Interfaces
Error wrapping
Generics
net/http internals
gRPC in Go
sync.Pool
io.Reader / io.Writer
Goroutine leaks
Escape analysis
Zero-allocation patterns
Race detector
Memory profiling with pprof
Interview decision:
Sorry, we need someone who actually knows when to use a goroutine.
Knowing Go features ≠ knowing Go engineering.
I’ve seen engineers spin up 100 goroutines for a task that should’ve been a simple for-loop.
They knew what a goroutine is.
They didn’t know why to spawn one.
Understanding fundamentals in Go means asking better questions:
---
1. Do you really need concurrency here?
Just because Go makes concurrency easy doesn't mean everything should be parallelized.
If your job is CPU-bound
— concurrency won’t give you a speedup.
If your job is I/O-light
— concurrency might hurt performance.
Many Go beginners accidentally create spinning goroutine storms for trivial tasks.
---
2. Should this be a goroutine or a worker pool?
Goroutines are cheap — not free.
Thousands? Fine.
Millions? You’ll crash your service.
Worker pools add backpressure, limit concurrency, and prevent cascading failures.
Correct concurrency is about control, not enthusiasm.
---
3. Is a channel even the right abstraction?
Channels are not the default.
Sometimes:
a simple slice is faster
a mutex is simpler
a pipeline is unnecessary
atomic values give lower overhead
Channels introduce synchronization.
Synchronization introduces latency.
Engineers who love channels often write code that’s “clever” instead of correct.
---
4. How will this context propagate?
Most Go outages happen because developers:
forget to cancel contexts
pass background context everywhere
leak goroutines waiting on dead channels
ignore deadlines
If your system doesn’t handle cancellation properly, you don’t have a Go service — you have a time bomb tbh.
---
5. Have you run the race detector, profiler, and escape analyzer?
If you write Go without:
go test -race
go tool pprof
go build -gcflags="-m"
…then you're guessing, not engineering.
Being able to explain:
why a value escapes to the heap
why CPU usage spiked
why memory is ballooning
why goroutines aren’t releasing
is what separates a “Go tutorial graduate” from a real Go engineer.
---
6. Does this service need Go?
Go shines in:
high-throughput APIs
distributed systems
infrastructure tools
networking services
event processing
real-time pipelines
Sometimes Python is better.
Sometimes Rust is better.
Sometimes PostgreSQL stored procedures outperform your Go service entirely.
Knowing Go means knowing when not to use Go.
---
The best Go engineers aren’t the ones who know every feature.
They're the ones who can explain:
why this should NOT be concurrent
why this needs a mutex, not a channel
why this code must avoid allocations
why this API should return errors, not panics
why a simple goroutine is not a “system design pattern”
Anyone can memorize go routines + channels = concurrency.
Not everyone can architect a system that runs clean for months without leaking memory, burning CPU, or failing under load.
That’s the difference between Go as a language and Go as an engineering discipline.