Migrating from Go to Rust | corrode Rust Consulting
Migration Guides
Migrating from Go to Rust
by Matthias Endler
Published: 2026-05-19
Out of all the migrations I help teams with, Go to Rust is a bit of an outlier.<br>It’s not a question of “is Rust faster?” or “does Rust have types?”, Go already gets you most of the way there.<br>The discussion is mostly about correctness guarantees , runtime tradeoffs , and developer ergonomics .
A quick disclaimer before we start: this guide is heavily backend-focused .<br>Backend services are where Go is strongest, small static binaries, a standard library focused on networking, and an ecosystem of libraries for HTTP servers, gRPC, databases, etc.
That’s also where most teams considering Rust are coming from (at least the ones who reach out to me), so I think that’s the comparison that’s actually useful in practice.<br>If you’re writing CLI tools, embedded firmware, or game engines, some of this still applies, but to be honest, I’m afraid this is not the best resource for you.
For context, I’ve written about Go and Rust before: “Go vs Rust? Choose Go.” back in 2017, and later the “Rust vs Go: A Hands-On Comparison” with the Shuttle team, which walks through a small backend service in both languages.
What you will learn in this article
Where Go and Rust overlap, and where they diverge.
How Go patterns map to Rust.
What you gain from the borrow checker.
Where I tell people to keep Go and where Rust is worth the migration cost.
How to migrate Go services incrementally.
Where I’m Coming From
I’ll be upfront: I’m not a fan of Go. I think it’s a badly designed language, even if a very successful one. It confuses easiness with simplicity, and several of its core design tradeoffs (nil everywhere, error handling as a discipline rule rather than a type, the long absence of generics) point in a direction I disagree with.<br>That said, success matters! Go has captured a real and persistent share of working developers, hovering around 17–19% in the JetBrains Developer Ecosystem Survey. Rust is growing steadily but is still a smaller slice:
Go is clearly working for a lot of people, and a guide that pretends otherwise isn’t helpful.<br>So I’ll do my very best to be objective in this guide rather than relitigate old arguments. But you should know my priors so you can calibrate.
The other prior worth disclosing: I run a Rust consultancy; of course I’m biased!<br>More people using Rust is good for my business.<br>But I’ve also worked in both languages professionally and shipped Go services to production.
This guide is for Go developers who want an honest, side-by-side look at what changes when you move to Rust.
For a deliberately opposite take, I recommend reading “Just Fucking Use Go” by Blain Smith. Holding both views in your head at once is more useful than either one alone.
If you prefer to watch rather than read, here’s a video from the Shuttle article above, read and commented by the Primeagen:
A First Look At The Most Important Commands
Go developers already have one of the cleanest toolchains in the industry.<br>Back in the day, it started off a trend of “batteries included” toolchains that give you a single, consistent interface for building, testing, formatting, linting, and managing dependencies. I’m glad that Rust followed suit, because it’s a great model. It’s one of my favorite parts about both ecosystems.
cargo has even more built-in:
Go toolRust equivalentNotes<br>go.mod / go.sumCargo.toml / Cargo.lockProject config and dependency manifest<br>go get / go mod tidycargo add / cargo updateAdd and resolve dependencies<br>go buildcargo buildCompile the project<br>go run .cargo runBuild and run<br>go test ./...cargo testTesting built into the toolchain<br>go vet ./...cargo clippyLinter, Clippy is significantly more opinionated than vet<br>gofmt / goimportscargo fmtAuto-formatter, zero config<br>golangci-lint runcargo clippy -- -D warningsStrict lint mode<br>go install ./cmd/foocargo install --path .Install a binary<br>go doccargo doc --openGenerate and view API docs<br>pprofcargo flamegraph / samplyCPU profiling<br>govulncheckcargo auditVulnerability scanning against an advisory database
The big difference is that in Go you typically reach for third-party tools (golangci-lint, mockgen, air, goreleaser) to fill gaps.<br>In Rust, the first-party ecosystem covers more out of the box.<br>Things that do require external crates (e.g. cargo watch, cargo nextest) install with one command and feel native, e.g. cargo install cargo-nextest gives you cargo nextest right away.
Both communities have converged on the same insight about formatters: a single canonical style, even an imperfect one, is worth more than the bikeshedding it eliminates.
Gofmt’s style is no one’s favorite, yet gofmt is everyone’s favorite.
— Rob Pike, Go Proverbs
The same is true of rustfmt: not everyone likes every detail, but the absence of style debates in code review is worth far more than the occasional formatting preference you’d have made...