Learning Rust #3: crates.io & publishing your package
Last December I finally started learning Rust and in January I built and published my first app with Rust: 235. Learning Rust is my new monthly blog series that is defnitely not a tutorial but rather a place for me to keep track of my learning and write about things I've learned along the way.
Learning Rust series
- Learning Rust #1: Pattern Matching
- Learning Rust #2: Option & Result
- Learning Rust #3: crates.io & publishing your package (you are here)
- Learning Rust #4: Parsing JSON with strong types
- Learning Rust #5: Rustlings
- Learning Rust #6: Understanding ownership in Rust
- Learning Rust #7: Learn from the community
- Learning Rust #8: What's next?
- Learning Rust #9: A talk about rustlings
- Learning Rust #10: Added new feature with a HashMap
This week I wanted to take a look at the publishing and distribution of Rust applications. It presents a major difference to what I'm used to and what I love in the web app world so I'll discuss that first and then look at the practicalities and the documentation of getting your application to the computers of your users.
When I was young, we bought software from store
I want to start this with a bit of a story. When we got our first family computer in the early 1990s, we'd buy software in floppy disks from a computer store. This was true a decade later with the small change that the software was distributed in CDs.
The Internet was young and the connections and download speeds were not suitable for mass scale distribution of software as downloadables. In the early 2000s, I started to use some online services like forums and early versions of social media via browser.
When I was 15, I knew I couldn't write my own software, get it to store shelves and have people buy it. I was just a beginner developer learning the first steps. So building things on the web, to be used with browsers was what I decided to go with. It probably wasn't as concious and thoughout decision as I see it through the goggles of nostalgy. However, the fact that I could build something, upload it (we used to deploy by moving PHP files with FTP client to the server) and it would available to anyone interested in using it was definitely a major reason for why I fell in love with the web as a medium.
So, for 15 years, almost everything I built, was deployed to a webserver somewhere and accessed via browser. I did build some tools for myself that were run locally but they were never meant to be given to other people so distribution was not a factor.
As the web development as a field progressed over the 15 years, distribution became even easier and instead of ftp'ing bunch of files to the server, we started to set up automatic deploys and working with version control. But the essence of distribution didn't change: I make a change and it's available to everyone without needing any action from them.
Then I built my first Rust binaries
This brings us back to 2021 and me learning Rust. When the end result of your work is a binary executable, everything in terms of distribution changes. No longer, can I fix an issue quickly and have it in front of every user within minutes.
Thanks to the internet and Rust's package ecosystem, there's no need to burn the app on a CD, put into a beautiful cardboard box and sell in stores. Now people can download it in seconds, update it easily and get things rolling with the new version.
But there's still one major difference: people need to update their app manually. There might be some ways to let people know that their application needs updating: first thing that comes to mind is making an API call to a server that returns the last version number and if it's newer than what the user has, print a "you should update" message. Thinking of it now, I might end up doing that before 235 hits version 1.0. Let me know if there's a better way.
But still, people may run your application for months or years without checking for updates, especially if it works. Or they might abandon it quickly if there are annoying bugs and when they notice it, there ain't no new version yet.
The authority of updates moves from the developer to the user. And that changes so much.
crates.io
Rust's package registry is called crates.io. If you're a Javascript developer, it's similar to npm. For Python users, it's similar to PyPi. It's the place where you find the tools you need to write great Rust programs without reinventing the wheel. It's also where you can install 235 from.
cargo install nhl-235
is the command line command that pulls the
package and builds it.
To publish Rust code in crates, you need two thing: account in crates.io and
Cargo.toml
file with
certain information you can check from the docs. After those are correctly done, cargo publish
transfers your
code via the highway of information to the package registry so others can
install it and use it.
I really enjoy the process. It's developer experience is fantastic and once
I've gotten a new release version done, I just publish it and people can
update it with cargo install nhl-235
. So good.
Building binaries
You don't have to share your program in crates.io though. Since the result of the build process is a binary, you can just share that. I'm still learning how to use the Releases page of GitHub but whenever I publish to crates.io, I upload a new release build to GitHub to which I also link from my website.
This allows people to download and run your program without any need for the Rust language tooling installed.
I develop 235 on a macos and I'm not 100% sure if my builds work on any machine. It's on my todo list to learn more and test it more thoroughly but so far, nobody has complained. If you wanna give me a hand and use Windows or Linux, download the latest release from here and run it from the command line and let me know in Twitter if it works or not.
A huge benefit of the binaries compared to crates.io is that the end user doesn't need any Rust tools installed and I gain full control over distribution. And those updates? It's bit more of a hassle since people need to go and download the binaries again and replace the old ones.
Eventually 235 will reach design and technical maturity where it won't be updated with new features and hopefully won't have breaking bugs anymore. At that point, the need to update constantly will thankfully disappear. Until I may have to do some changes to the API.
Making a release is more deliberate
One thing I've noticed is that when I can't just deploy a change or fix in a matter of minutes, I need to be much more deliberate, test things out more and figure out if the design of the program is correct. In the beginning, it's more okay to experiment especially as I'm learning the language but as I reach version 1.0, I'm looking to only make changes in larger chunks.
All in all, publishing 235 via crates.io and as binaries has been a very educational process and a refreshing change of pace compared to my usual web development projects.