Rust — Packages
The hierarchy, top-down
Package (Cargo.toml at the root) ← what you ship/build
├── Crate: library (lib.rs) ← reusable code unit
├── Crate: binary (main.rs) ← executable entry
└── Modules inside each crate ← organization within
- Crate = smallest compilable unit (a lib or a bin)
- Package = bundle of one-or-more crates + manifest
cargo new myapp creates a package with ONE binary crate.
Anatomy of a package
myapp/
├── Cargo.toml ← name, version, dependencies
├── src/
│ ├── main.rs ← binary crate root
│ └── …modules…
└── tests/ ← integration tests (optional)
Minimal Cargo.toml
[package]
name = "myapp"
version = "0.1.0"
edition = "2021"
[dependencies]
Adding a library crate to the same package
Create src/lib.rs:
// src/lib.rs — the LIBRARY crate root
pub mod math {
pub fn add(a: i32, b: i32) -> i32 { a + b }
}
Now main.rs can import it as an external-looking crate:
// src/main.rs — the BINARY crate
use myapp::math::add; // crate name from Cargo.toml!
fn main() {
println!("{}", add(2, 2));
}
This split is standard practice: logic in lib.rs, thin CLI wrapper in main.rs. It also unlocks unit testing of internals.
Dependencies — pulling from crates.io
[dependencies]
rand = "0.8"
serde = { version = "1.0", features = ["derive"] }
$ cargo build
Updating crates.io index
Downloading rand v0.8.5 …
First build downloads + compiles everything into Cargo.lock (exact versions, committed to git for apps). Subsequent builds are instant until deps change.
Useful commands
cargo add rand # edit Cargo.toml for you
cargo update # bump deps within semver ranges
cargo tree # dependency graph
cargo doc --open # docs for your code AND dependencies
Workspaces (preview)
Multiple related packages under one repo:
# root Cargo.toml
[workspace]
members = ["core", "cli", "server"]
Shared target dir, versioned together — how large Rust projects stay manageable.
Package naming & conventions
- lowercase with hyphens on crates.io (
my-cool-tool) - code identifiers stay snake_case regardless
- binary targets may live in
src/bin/*.rs— each file becomes its own executable
Mini Practice
- cargo new; add rand; print three random numbers.
- Create lib.rs with a pub function; call it from main.
- Run cargo tree; count transitive dependencies.
- Add serde with derive feature; confirm compile.
- Sketch which files you'd create for a CLI + core-library app.
Next: crates →
Related Topics
Frequently Asked Questions about Packages
What is Packages in Rust?
Packages is a fundamental concept in Rust. This lesson explains it step by step with clear examples, making it easy for beginners to understand.
How do I learn Packages?
Start by reading the explanation above, then try the code examples. Practice by modifying the examples and experimenting with different values. Hands-on practice is the best way to learn Packages.
Why is Packages important in Rust?
Packages is essential for Rust development. Understanding this concept will help you write better code and solve real-world problems more effectively.