Modules and Crates in Rust
Rust organizes code with modules (namespaces) inside a crate (compilation unit). A package can contain one or more crates.
Module basics
- Declare modules with
modand place code in files or inline blocks. - File layout rules:
mod utils;looks forutils.rsor autils/mod.rsfile.- Nested modules follow directories:
mod net { mod http { ... } }maps tonet/http.rsornet/http/mod.rs.
// src/lib.rs (crate root)
pub mod utils; // exposes src/utils.rs
mod internal; // private to the crate
Visibility and paths
- Private by default. Use
pubto export. - Fine-grained options:
pub(crate),pub(super),pub(in path). - Paths can be absolute (
crate::or external crate name) or relative (self::,super::).
pub mod math {
pub fn add(a: i32, b: i32) -> i32 { a + b }
fn hidden() {}
}
use crate::math::add as plus;
Re-exports (public API design)
Re-export internal paths to curate your public API surface.
mod details { pub mod io { pub fn read() {} } }
pub use details::io::read; // consumers call your_crate::read()
Crate roots and binary vs library
src/lib.rsis the library crate root.src/main.rsis a binary crate entry point.- Multiple binaries: place files under
src/bin/*.rs.
External crates and use
Add dependencies in Cargo.toml, then import items with use.
[dependencies]
serde = { version = "1", features = ["derive"] }
use serde::{Serialize, Deserialize};
Workspaces vs modules
- Modules are namespaces inside a crate.
- Crates are compiled units.
- Workspaces group multiple crates for unified builds and dependency resolution.
# Cargo.toml at repo root
[workspace]
members = ["core", "cli"]
Tips
- Keep internal structure private; re-export a tidy API.
- Prefer directory-based modules for larger trees.
- Avoid cyclical module dependencies by extracting shared pieces into a new module or crate.