Crates

In the Rust ecosystem, crates are either third-party libraries that you can import into your application, or they can be applications (binaries). The Cargo CLI tool is how you create and manage crates. Cargo is installed along with the Rust toolchain.

Crates can actually contain both libraries and binaries, however they can only contain a maximum of one library. If you choose to include binaries into your crate, then you can expose as many as you want to. Essentially, a Rust crate can contain lots of separate applications, but can only define a single library.

When you create a library or binary, you will have a metadata file called Cargo.toml. This file is customizable by you directly, and the Cargo CLI also makes modifications to it.

Create New Crate

If you want to create a new crate, open an empty folder in your terminal and run cargo init. By default, this will create a binary application. You can run cargo init --lib to create a crate that will be imported into other applications.

Add Binary to Existing Crate

Let's say you already have a Rust crate that declares a library, and you'd like to add an application entrypoint to it. In your Cargo.toml file, you can declare a new [[bin]] header to denote a new binary in your Crate. Underneath each [[bin]] header, you can define the name property to set the compiled binary (application) name. You can set the path property to indicate which Rust source code file contains the main() entrypoint function for the application.

[[bin]]
name = "mycoolapp"
path = "mycoolapp.rs"

Install Rust Tools with Cargo

You can install Rust applications from the crates.io registry. The cargo install command is used to install binaries (applications) that other developers have published to the registry.

For example, try running this command:

cargo install btop

This should compile btop and install the binary into your $HOME/.cargo/bin directory. To verify this simple list the files in that directory.

ls ~/.cargo/bin/

Publish Crate on Crates.io Registry

The crates.io registry is the central place where you can publish your libraries for other developers to consume. You can also search for Rust libraries on crates.io, that you can use in your own Rust applications or libraries.

The high-level process for publishing your own crate looks like this:

  • Login to the registry
  • Cutomize Cargo.toml metadata file
  • Run the publish command

We'll break each of these tasks down in the next few sub-sections.

Login to Registry from Cargo

Before you can publish to the crates.io registry, you'll need to login to the web interface with GitHub and generate an API token. Copy the API token to your clipboard and then run the following command to authenticate from the command line.

cargo login

You'll be prompted to paste your crates.io API token, and after hitting ENTER on your keyboard, you'll be authenticated to the registry.

Customize Cargo.toml

The Cargo.toml file contains metadata about your Rust crate. Running cargo init generates this file, but certain extra settings are required, in order to successfully publish your crate to the registry. For example, here are the settings I had to add to one of my projects, in order to publish it to the registry.

author = "Trevor Sullivan <trevor@trevorsullivan.net>"
license = "MIT"
description = "Btop CLI monitoring tool, re-imagined in Rust 🦀"

Make sure that you add these settings to your Cargo.toml file before you attempt to publish your Rust crate to the registry.

Publish Crate

Now that you've authenticated to the registry and customized your Cargo.toml file, let's publish your Rust crate. Run the following command from your project directory.

cargo publish

When attempting to publish a crate to the crates.io registry, you might receive the error below.

error: 10 files in the working directory contain changes that were not yet committed into git:

By default, the Cargo CLI is expecting your git working tree to be clean, before you publish. However, you can override this behavior by simply appending the --allow-dirty argument onto your cargo publish command.

cargo publish --allow-dirty