Many things are only available as C libraries, and re-implementing that all in Go would be costly. cgo has its downsides, but it can be a good trade-off. Even the standard library uses it (net
for DNS lookups, os/user
for user lookups) because it doesn’t re-implement 100% of the behaviour in Go.
Cross-compiling C code is still rather hard; you’ll need the target architecture’s C compiler and toolchain (e.g. CC=aarch64-linux-musl-gccgo build
to build an arm64 binary). None of that is installed by default so for most people cgo simply won’t work when cross-compiling; they need to take manual steps to set it up first.
cgo often isn’t strictly required (like in the net and os/user packages), so disabling it by default seems the most user-friendly option.
But there are no such constraints on the native platform, and it’s expected to work by default without any user setup; so why not enable it by default?