Modules & Project Structure

Rust project structure is a layered system: packages contain crates, crates contain module trees, paths name items, and visibility controls the public API.

Concepts

Patterns

Antipatterns

Example

mod api {
    pub fn version() -> &'static str {
        "1.0"
    }
}
 
pub use api::version;
 
fn main() {
    assert_eq!(version(), "1.0");
}

This tiny crate shows the stack: a module owns implementation, pub exposes an item, and pub use presents a short public path.

Best practice

  • ✅ Choose the smallest useful boundary: module before crate, crate before workspace.
  • ✅ Keep crate roots as readable API and module declarations, not as dumping grounds.
  • ✅ Use visibility to protect invariants and make public paths intentional.
  • ✅ Re-export stable public concepts instead of exposing incidental internal folders.

Pitfalls

  • ⚠️ Confusing Cargo package layout with Rust module layout.
  • ⚠️ Treating files as modules without understanding the parent mod declaration.
  • ⚠️ Making everything pub to quiet privacy errors instead of designing the API.
  • ⚠️ Using broad glob imports where explicit imports would make dependencies clearer.

See also

Packages and Crates · Crate Roots · Modules · Module Paths · Visibility and Privacy · The use Keyword · Splitting Modules into Files · Re-exporting with pub use · Library and Binary Package Layout · Workspace Project Structure · Cargo Workspaces · Cargo.toml Manifest

Sources