Crates & Packages
A package (Cargo project) contains one or more crates (compilation units): library (lib.rs) and/or binaries (main.rs, bin/*.rs).
Recipe
[package]
name = "myapp"
version = "0.1.0"
edition = "2024"
[lib]
name = "myapp"
path = "src/lib.rs"
[[bin]]
name = "cli"
path = "src/bin/cli.rs"When to reach for this: Splitting reusable library from CLI binary in one repo.
Working Example
// src/lib.rs
pub fn core_logic() -> i32 { 42 }
// src/main.rs
fn main() {
println!("{}", myapp::core_logic());
}What this demonstrates:
- Library crate exposes
core_logic - Binary depends on library crate in same package
- Package name matches lib for
use myapp
Deep Dive
cdylib/staticlib for FFI. autobins false to control bins. build.rs for build scripts.
Gotchas
- Binary-only crate no lib - Hard to integration test logic. Fix: Extract lib.
- Name mismatch lib vs package - Import confusion. Fix: Align names or document.
- Multiple bins share code - Duplication in mains. Fix: Shared lib module.
- pub in binary only - Not reusable. Fix: lib.rs.
- Edition mismatch deps - Resolver picks compatible.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| Workspace split crates | Clear boundaries | Tiny tool |
| Single binary | Script | Reusable library needed |
| proc-macro crate | Derive macros | Normal code |
FAQs
crate vs package?
Package cargo.toml; crate compiled artifact.rlib dylib?
Crate types for linking.tests crate?
tests/ integration separate crate.bench?
criterion external often.examples/?
example bins in cargo.publish?
One package per crates.io entry usually.lib path default?
src/lib.rs.main multiple?
[[bin]] table.no_std lib?
#![no_std] in lib.rs.doc?
cargo doc --open.Related
Stack versions: This page was written for Rust 1.97.0 (edition 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, and Polars 0.46+.