Rust Crates: Your Unit of Compilation
A crate is the smallest unit of code the Rust compiler handles—either a runnable program (binary) or a shareable library. A package, defined by Cargo.toml, bundles one or more crates. The footgun: a package can have many binaries but only one library.
WHY IT EXISTS Rust needs a fundamental, compilable boundary for code. Crates serve this purpose, allowing the compiler to distinguish between runnable programs and reusable libraries. This structure is the foundation for sharing code and managing dependencies in the ecosystem.
THE MENTAL MODEL Think of a crate as a single "output" from the compiler. It's either an executable file you can run (a binary crate) or a library file you can link against (a library crate). A "package" is the project folder, containing the instructions (Cargo.toml) to build one or more of these crate outputs.
HOW IT WORKS The Rust compiler, rustc, operates on single crates at a time. Each crate has a "root" source file where compilation begins. By convention, Cargo tells the compiler that src/main.rs is the root of a binary crate and src/lib.rs is the root of a library crate. A package, defined by its Cargo.toml file, organizes these. A package can contain at most one library crate but can have many binary crates by placing files in the src/bin directory; each file in that directory becomes a separate binary crate.
WHEN TO USE IT You are always working with crates in Rust. When you build a command-line tool or a server, you are building a binary crate, which must have a main function. When you want to create shared, reusable functionality for other projects, you build a library crate, which does not have a main function.
WHEN NOT TO USE IT The concept is fundamental, but the distinction is important. Avoid putting shared, reusable logic inside a binary crate's main.rs. Instead, place that logic in a library crate (lib.rs) and have your binary crate depend on it. This promotes modularity and makes your code easier to test and reuse.
ONE CANONICAL EXAMPLE Running cargo new my_app creates a package named my_app. This package contains a single binary crate, also named my_app, with its root at src/main.rs. If you then add a src/lib.rs file, your package now contains two crates: a library and a binary, both named my_app. The binary can then use code defined in the library.
Read the original → doc.rust-lang.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.