Modules in Rust help you organize code by grouping related functions, types, and constants together. You define modules using the mod keyword and use them to break large files into smaller, manageable pieces.
As your Rust project grows, putting everything in one file becomes messy. That is where modules come in. They allow you to split logic into parts, reuse code across files, and define clear boundaries between features.
In this post, I will show you how to define, use, and structure modules properly. If you are already comfortable with functions and structs, learning modules is the next step toward writing real-world Rust projects.
What Is a Module?
A module is a named block of code that holds definitions such as functions, structs, enums, constants, and other modules.
You create a module using the mod keyword.
Example
mod greetings {
pub fn hello() {
println!("Hello from the module!");
}
}
This defines a module called greetings with one public function.
Using a Module
To call something from a module, you use the path syntax:
fn main() {
greetings::hello();
}
This works because hello is marked pub, meaning it is public and accessible outside the module.
Visibility with pub
By default, everything inside a module is private. Use pub to expose functions, structs, or other items:
mod math {
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
}
Now you can access math::add from outside the module.
Nesting Modules
You can nest modules inside other modules:
mod outer {
pub mod inner {
pub fn show() {
println!("Inside nested module");
}
}
}
Call it like this:
outer::inner::show();
You can also use use to bring paths into scope:
use outer::inner;
inner::show();
Modules Across Files
To keep your codebase clean, move modules into their own files:
In main.rs or lib.rs, declare the module:
mod utils;
Create a file named utils.rs in the same directory. In utils.rs, define public items:
pub fn say_hi() {
println!("Hi from utils!");
}
Now you can call utils::say_hi() from main.rs.
For nested modules, use a folder with mod.rs or use Rust 2018-style (recommended):
- Create a folder math/
- Inside it, add mod.rs or directly use add.rs, subtract.rs, etc.
- Declare in math.rs: pub mod add;
Real-World Example
Imagine a blog app. You might organize it like this:
src/
├── main.rs
├── posts.rs // mod posts;
├── users/
│ ├── mod.rs // pub mod auth;
│ └── auth.rs
You can now access nested logic like: users::auth::login()
Benefits of Using Modules
- Keeps related code together
- Hides internal logic by default
- Makes code easier to test and maintain
- Encourages reusable structure
Summary
Modules in Rust help you organize your code logically and cleanly. With mod, pub, and proper file structure, you can build clear and scalable applications. Learning to use modules well is key to writing idiomatic Rust.
Rust Learning Path
- Introduction to Rust
- Setting Up Rust Development Environment
- Your First Rust Program
- Variables and Mutability in Rust
- Constants and Immutability in Rust
- Type Annotations and Inference in Rust
- Variable Shadowing and Scope in Rust
- Rust Primitive Data Types
- Working with Strings in Rust
- Every Operator in Rust Explained
- Tuples in Rust
- Arrays and Slices in Rust
- Rust Decision Making: if & match
- Loops in Rust
- Reading Input from the Console in Rust
- Mastering Rust Functions (For Beginners)
- Understanding Ownership in Rust
- Borrowing and References in Rust
- Copy Types vs. Move Semantics in Rust
- Cloning Data in Rust
- Methods and Associated Functions in Rust
- Enums: Defining Variant Types in Rust
- Pattern Matching with Enums in Rust
- The Option Type: Null Safety in Rust
- Error Handling with Result
- Unrecoverable Errors in Rust
- Organizing Code with Modules in Rust
- Cargo Basics: Rust Package Manager
- How to Use External Crates in Rust