Post

Starting Rust in 2025

Maybe I should start over

Starting Rust in 2025

TL;DR

Why Rust?

If you’re reading this you’re probably already interested in Rust and know why it’s got an exciting new place among programming languages. If you’re new to Rust, here’s why it’s generating so much excitement! Rust enforces memory safety through its compiler rustc with the “borrow checker” that tracks object lifetimes. Rust ships with an integrated toolchain that includes a package manager (Cargo), a code formatter (rustfmt), a language server (rust-analyzer), and more. This makes it easier to get started with Rust development without needing to set up a complex environment. It’s still early days but you can find Rust in production in Firefox, Dropbox, Linux and more. Rust has recently been picking up momentum with even the White House urging the industry to move to memory safe languages.

Why the plan?

I’ve gone into plenty of new languages over my last 15 years of programming but learning Rust has been a very different experience compared to most other languages. You can jump into Rust with minimal studying and that will be fine for most tasks but there is definitively something pushing you into theory along the way, even if you have prior experience in a systems level language like C or C++. This is more than an academic challenge, spending time on the theory and potentially revisiting your computer science fundamentals will help in understand Rust’s ownership, borrowing and lifetime systems.

A rollercoaster of emotions A rollercoaster of emotions

In the highly scientific™ diagram above I’ve tried to illustrate what I think the Rust learning curve looks like. Unlike most other languages the curve gets really spiky every time a new concept is introduced. You start off easy with a toy application where cloning to get around lifetimes makes life easy. Then you get into lifetimes and it suddenly gets really hard until you learn some patterns and understand the compiler’s outputs better. Async is the next beast but if you use clone it’s still very manageable. At the end you put lifetimes and async together for the dreaded Send + Sync + 'static, a dragon that is very hard to tame. If you go to the next step without really learning the previous one things risk getting really hard from my experience so far.

The goal with this post is to give a path of learning that sets you up for success in forging your own path forward, be it delving deeper into the language itself or to start building your own projects, so let’s get to it!

The plan

First, should you read the Rust book before doing anything else? Personally, I don’t think so unless you’re really good at retaining information from just reading. The Rust book is an amazing resource compared to the old days of thick, academic C++ literature and I suggest reading it early into the learning process but not upfront before getting into at least some practical exercises.

Starting point

A half-hour to learn Rust

Let’s begin with some light reading to lay the foundation. Although a few years old at this point the excellent article A half-hour to learn Rust from fasterthanlime is still one of the best starting points you can find for a quick intro to Rust basics. In it you’ll find everything from basic variable assignment to generics, lifetimes and closures. It’s a great reference that you’re guaranteed to keep coming back to throughout your Rust journey.

Rustlings

This should be enough for you to get started on the next step, Rustlings. Rustlings is a set of small programming exercises that will take you on a tour through Rust paired with the Rust book. If you’re an experienced programmer you will absolutely blast through these in a matter of hours but this is your first opportunity to tie theory to practice. Each set of exercises comes with recommended reading and to get the full value from Rustlings I suggest taking the time to at least skim the suggested chapters so you can more easily refer back to the relevant parts later.

&str and String

At this point you’ve got the foundational skills required to start building things but I suggest first getting a firm grasp of &str and String before moving further. I’ve seen more than one developer get bogged down by this, especially if they’re not well versed in the hellscape that is strings in C++. &stress about &Strings serves as an intuitive intro to the differences between string types in Rust. If you prefer to dive straight into the technical definitions there’s a multitude of different articles available such as String vs &str in Rust or String vs str in Rust: Understanding the difference.

Review

Now is a great time to pause and review your learnings so far to make sure you’re on the right track. Make sure you feel comfortable with the terminology and concepts so far, as they will serve as the foundation for the more complex ideas coming up. Rustcamp chapter 0 has a great set of questions that let’s you review if there is any terminology or concepts that you should brush up on further. You might wonder if it’s really necessary to know the difference between a fat and thin pointer if all you’re planning to do is build web services with Axum and Tokio? Even if you’re focused on building web services, understanding these low-level concepts will give you a better grasp of Rust’s memory model, making it easier to write efficient, bug-free code. As you delve deeper into Rust much of this terminology will become ubiquitous across literature, articles and talks. The earlier you master it the easier the rest of your learning will be even if it isn’t strictly related to your specific domain.

Delving deeper

Learn Rust With Entirely Too Many Linked Lists

We now have the basics around syntax, terminology and philosophy in Rust. I believe the next step is to get into common problems, idioms and some deeper theory at this point. I think the best way to do start that is with Learn Rust With Entirely Too Many Linked Lists. Another linked list? You’ve already implemented it 20+ times in multiple different languages and you haven’t used one in production for your entire career so what is the point? Well turns out there is a lot of inherent complexity when it comes to cyclic references and recursive structures if you add a borrow checker on top that enforces strict correctness in memory access. You’ll encounter challenges like borrowing across multiple parts of a list or managing ownership of nodes in a cyclic structure without risking memory leaks or dangling pointers. It’s also a good starting point for some standard traits such as iterator traits and drop.

Tour of Rust’s Standard Library Traits

Next up, more traits! The previous exercise was a great jumping off point for checking out more standard library traits. Traits are one of the most powerful (and fun) features of Rust and the primary way to implement polymorphism and reuse code. I don’t think it’s necessary to learn all of these off the bat but if you’ve seen them once that makes it easier to remember which ones you should use. Some, such as From/Into, Clone, Copy, Debug and Display, will be daily drivers. For this I recommend the excellent blog post Tour of Rust’s Standard Library Traits. It’s well worth keeping around as reference material too.

Let’s build something

Now you’re ready to build something that is a step above a simple toy project. If you got this far I’m assuming you’re a highly motivated person to begin with and have plenty ideas of what you want to build. I’ll still offer some project suggestions along with my approach to building learning projects. These projects are more about gaining deeper insights into Rust than creating something functional. Regardless of what project you decide to build I suggest it fulfills most if not all of the following.

  1. Have a clear definition of done. What should the project include and what should you have learned at the end?
  2. Use and abuse what you want to learn. Newtypes? Put them everywhere, even if it doesn’t make sense at first glance. Error handling? Implement your own errors everywhere before reaching for thiserror or anyhow.
  3. Share your learnings! Formulating what you learned for someone else to understand let’s you review and make sure you actually understood what you practiced.
  4. Make it reasonably sized. This ties into point 1 but it bears repeating. Could you recreate Bevy and become an expert in Rust? Probably but you’re more likely better off spending 10-20 hours on a smaller project with a highly focused goal then moving on.
  5. Avoid tutorials if you can. Tutorials make for great material if you want to implement a specific thing but when the goal is to learn the language itself I believe you’re more likely to get stuck in tutorial hell than reaching success.

Some suggestions for projects:

CHIP-8 emulator

I recently built my own CHIP-8 emulator and it was a really fun experience. It’s very different project compared to what I would come up with on my own, comes with a strict start and end and you can scale how involved you decide your implementation to be quite easily. It’s quite heavy on low-level system concepts with plenty of room to use and abuse different Rust idioms such as Newtypes. The biggest caveat is that it’s most likely not going to be heavy on lifetimes, which could be a good or bad thing depending on what you want out of your first project.

Advent of Code

We know it, we love it. Advent of Code serves as a huge repository of various challenges that let’s you choose how difficult you want it to be. I personally prefer it over Leetcode for learning because the problems are generally multifaceted with room for choosing how intricate your solutions should be. Also works great to come back to between other projects to mix it up instead of crunching all of it in one go.

Entity Component System (ECS)

Entity Component Systems are all the rage in Rust, in large part because Rust lends itself very well for data driven game systems and in many ways does not work at all for the traditional OOP game object model. This is a great starting point to work on lifetimes, iterators and generics.

CPU path tracer or ray tracer

Another classic project where you can choose your own difficulty according to ambition. Build your own math implementations, squeeze maximum performance and support multiple 3D formats or pull some crates to do the heavy lifting and piece it together. As a bonus you’ll have a cool looking visual end result to look at. I recommend specifically CPU because involving the GPU means you’ll probably spend more time researching how to get your code running on a GPU and dealing with host/client issues rather than programming actual Rust.

Lifetimes

At this point you will most likely have stumbled over lifetimes a lot. Lifetimes are a fundamental part of Rust’s memory safety model. Understanding them is key to avoiding issues like dangling references and data races. It’s common to feel confused by them at first, but revisiting the concept after getting hands-on experience can make things click. That’s why now is a good time to go read Common Rust Lifetime Misconceptions, another great blog post by pretzelhammer. I also recommend “but what is ‘a lifetime” for a great alternative approach at explaining how lifetimes work.

Next steps

Congratulations, you should now have a solid enough foundation and collection of reference material to continue down your own path of Rust learning! I do recommend doing at least one more small, single threaded project at this point where you do your best to challenge your mastery of the borrow checker. Rust’s learning curve is steep and you will most likely have to revisit concepts such as lifetimes and traits multiple times as you progress. Once you mix in async the difficulty will rise quite sharply in my experience but if you’re feeling adventurous you should have the prerequisite knowledge to get stuck in. If you do decide to get into async I recommend first reading Async Rust can be a pleasure to work with (without Send + Sync + 'static) for a quick tour on why async Rust currently works as it does.

Conclusion

Writing this I realized I had skipped some steps myself in my early Rust learning that would have made life significantly easier. Being diligent when studying topics such as lifetimes and how traits are implemented before trying to build anything too advanced would have been very helpful compared to what I did which was jump straight into building my own wgpu renderer. I am actually planning to go back and skim through this learning plan (even if I’ve done large parts of it) just to refresh my memory and solidify the basics before I progress on more projects. I look forward to seeing more and more people learn and enjoy Rust in 2025! If you found this blog helpful or think there are better paths to learn Rust please let me know, I’d love to hear it!

This post is licensed under CC BY 4.0 by the author.

Trending Tags