A while back I found myself looking for a language that could fill an interesting gap in my toolbox.
I wasn’t looking to replace Java. I wasn’t trying to write kernel modules. I certainly wasn’t planning to become one of those developers that somehow manages to mention memory safety in every conversation.
I simply wanted a language that could produce efficient standalone binaries, consume very little memory, and provide stronger guarantees than the languages I typically use day-to-day.
Like most developers approaching Rust, I had already heard all the warnings.
“The borrow checker is brutal.”
“Ownership is impossible to understand.”
“The learning curve is vertical.”
After spending some time with Rust, I discovered that none of those are the most interesting things about the language.
The most interesting thing is that Rust subtly changes the way you think about software design.
There are already countless articles explaining ownership, borrowing and lifetimes. The official Rust Book does a far better job of teaching those concepts than I ever could.
Instead, here are some things I learned while learning Rust.
The Compiler Is Not Your Enemy
My first few days with Rust were frustrating. I would write code that seemed perfectly reasonable, hit compile, and immediately be greeted by a wall of compiler errors. Coming from languages like Java and Go, this felt unnecessarily strict. Surely the compiler should trust me a little more?
After a while, I noticed something interesting. Almost every time I found myself fighting the compiler, I eventually discovered a flaw in my own design. Maybe ownership wasn’t clearly defined. Maybe state was being shared too freely. Maybe a function was trying to do three different jobs at once.
The compiler wasn’t preventing me from writing software. It was preventing me from postponing design decisions until production. That’s a very different thing. Over time I stopped viewing compiler errors as obstacles and started treating them as code reviews. Occasionally harsh code reviews, admittedly.
Ownership Is Really About Responsibility
Most discussions around Rust focus on memory safety. No null references. No use-after-free bugs. No accidental data races. Those outcomes are fantastic, but I don’t think they’re the real story. The bigger lesson is responsibility.
Rust forces you to answer questions that many other languages allow you to ignore. Who owns this value? Who is allowed to modify it? How long should it live? Can it be shared? Can it be transferred? These are architectural questions disguised as language features.
In many systems, ownership eventually becomes a production problem. In Rust, ownership becomes a design conversation. That feels like a much better place to solve it.
Immutable By Default Changes How You Think
One feature I initially dismissed was immutability by default. At first it felt unnecessary. Why should I need to explicitly mark variables as mutable? Wouldn’t it be easier if everything was mutable until proven otherwise, you know like “sane” languages?
The longer I worked with Rust, the more I appreciated this design choice. When reading a Rust codebase, mutable state becomes highly visible. The parts of the system capable of changing are clearly marked. The parts that are stable are equally obvious. This dramatically reduces the mental effort required to understand unfamiliar code.
I’ve come to realise that many difficult bugs are really state-management bugs in disguise. The less mutable state you have floating around, the easier life becomes.
Concurrency Feels Less Like Magic
I’ve written concurrent software in a variety of languages over the years. The workflow generally looks something like this:
- Add threads.
- Add locks.
- Add more locks.
- Wonder whether you’ve added enough locks.
- Find out in production you did in fact NOT add enough locks.
Rust approaches concurrency differently. Its type system and ownership model are deeply intertwined with concurrency guarantees. Many mistakes simply cannot compile. That doesn’t remove the need for careful design. You can still (and I have!) build terrible concurrent systems in Rust.
The difference is that entire categories of race conditions and memory issues disappear before the application ever runs. The result is that concurrency feels less like gambling and more like engineering.
Error Handling Became More Intentional
One of my biggest adjustments was Rust’s approach to errors. Like many developers, I was accustomed to exceptions.
Initially, Rust’s Result<T, E> approach felt verbose.
Every operation seemed to require explicit acknowledgement that something might go wrong. Then it dawned on me that this was precisely the point. Many languages make it easy to ignore failures until much later. Rust encourages the opposite. If something can fail, that possibility becomes part of the function signature.
The caller is forced to engage with it. The code communicates its risks up front. That’s surprisingly refreshing.
Fast Software Is Usually Boring Software
Before learning Rust I assumed most of its performance benefits came from clever compiler optimisations.While the compiler certainly helps, the bigger lesson was much simpler.
Fast Rust code is often boring. It uses straightforward data structures. It avoids unnecessary allocations. It keeps memory access predictable. It minimises unnecessary work. In other words, it follows many of the same principles that good engineers have been advocating for decades.
Rust simply makes it easier to stay on that path. The language nudges you toward efficient designs rather than relying on heroic optimisation efforts later.
Cargo Might Be Rust’s Best Feature
Everyone talks about ownership and borrowing. Far fewer people talk about Cargo. That’s a mistake. Cargo handles project creation, dependency management, testing, building, documentation and publishing with remarkable consistency.
Need to start a new project? Cargo. Need to run tests? Cargo. Need to build release binaries? Cargo. Need to publish a crate? Cargo.
After spending time in ecosystems where half a dozen tools need to be stitched together manually, Cargo feels refreshingly cohesive. Great languages are important. Great workflows are arguably more important.
Cargo delivers both.
Clippy Is The Code Reviewer That Never Sleeps
The first time I ran Clippy, I expected another linter. The kind that complains about formatting while completely ignoring questionable design decisions. Clippy turned out to be considerably more useful. It spots unnecessary allocations and highlights inefficient patterns. It even identifies code that works, but could be simpler, clearer or faster. It rolls a lot of static analysis tools into one.
What surprised me most is that experienced Rust developers often care as much about passing Clippy as they do about passing compilation. That sounds excessive until you’ve used it for a while.
Many Clippy warnings aren’t really warnings. They’re lessons. The tool consistently nudges developers toward writing more maintainable and more idiomatic Rust. Every now and then Clippy points out something that makes me wonder why I didn’t see the simpler solution myself. That’s probably the highest compliment I can give a linter.
And you know who else loves Clippy? LLM’s. Clippy gives immediate actionable feedback to your coding harness for fast feedback loops.
Cargo Audit Makes Security Boring
Most developers care about security. Most developers also have deadlines. Unfortunately those two things don’t always get along. Dependency vulnerabilities often become tomorrow’s problem. Or next sprint’s problem. Or somebody else’s problem.
Rust’s ecosystem includes Cargo Audit, which can scan dependency trees for known security advisories. The experience is refreshingly straightforward. Run a command. Receive an answer.
No dashboards. No lengthy configuration. No enterprise-grade complexity with central servers and authorizations. Just a clear indication of whether your project depends on something that shouldn’t be there. Good security tooling is often invisible enough that people actually use it. Cargo Audit falls squarely into that category.
The Tooling Raises The Floor
People frequently claim that Rust makes developers write better software. I’m not entirely convinced that’s true. Excellent developers can produce excellent systems in almost any language. What Rust seems particularly good at is raising the minimum standard.
The Rust team took the best tooling philosophies of Java and GO and made them better. The compiler catches correctness issues. The ownership system catches design problems. Clippy catches questionable patterns. Rustfmt eliminates formatting debates. Cargo Audit highlights dependency risks. Testing is integrated into the normal workflow.
None of these tools are revolutionary on their own. Together they create an environment where many bad decisions become harder to ignore. That combination is surprisingly powerful.
It is also these deterministic and opinionated tools that allow fast feedback loops in agentic workflows.
Rust Is Teaching Me Patience
The most unexpected lesson from Rust probably has nothing to do with technology. Rust rewards slowing down. The quickest way to write Rust isn’t necessarily to type faster, it’s to think more carefully before you start typing.
The compiler asks questions about ownership. Clippy asks questions about clarity. Cargo Audit asks questions about dependencies. The ecosystem continuously encourages deliberate decision-making.
Initially that can feel frustrating, especially when you’re eager to get something working. But six months later, when you’re maintaining the same codebase, those extra moments of thought often pay for themselves many times over.
Final Thoughts
I started learning Rust because I wanted efficient binaries, predictable performance and low resource usage. What I found was something more interesting.
Rust isn’t merely a programming language. It’s a collection of ideas, tools and constraints that encourage careful software design. Ownership teaches responsibility. Clippy encourages simplicity. Cargo Audit promotes security. Cargo ties everything together into a workflow that feels remarkably polished.
Whether Rust becomes your primary language or simply another tool in your arsenal, I think it’s worth experiencing the perspective it brings.
Just don’t be surprised if the compiler occasionally seems stubborn.
More often than not, it’s trying to save you from yourself.

