How to include a module from another file in Rust: from beginner to confident user
\n\nHave you ever been writing code in Rust and suddenly realized that your main.rs is turning into a 500-line giant monster? Sound familiar? Or perhaps you're just starting to learn Rust and want to understand how to properly organize code by splitting it into multiple files. The question "How can I include a module from another file from the same project?" is one of the most popular on Stack Overflow, and for good reason. Rust's module system is both powerful and... a bit non-obvious for beginners.
In this article, we'll break down everything from A to Z: how to create a module, how to include it, what pitfalls exist, and how to avoid stepping on rakes. Let's go!
\n\nWhy are modules in Rust not just "include"?
\n\nIf you come from Python or JavaScript, you're used to import or require. In Rust, things are a bit different. There is no magical "grab the file and use it". Instead, Rust uses a declarative module system. You must explicitly tell the compiler: "Hey, this file is part of my project, and this is what it's called."
The main rule to remember is: every file is a module, but not every module is a file. Sounds like a riddle, right? We'll figure it out now.
\n\nProject structure: where to start
\n\nSuppose you have a project with this structure:
\n\nmy_project/\n├── Cargo.toml\n├── src/\n│ ├── main.rs\n│ ├── greetings.rs\n│ └── utils/\n│ ├── mod.rs\n│ └── helpers.rs\n\nHere, greetings.rs is a simple module, and utils/ is a folder with a module. Let's learn how to include them.
Method 1: Including a simple file-module
\n\nThe most basic case. You have greetings.rs with a function:
// greetings.rs\npub fn say_hello() {\n println!("Hello from the greetings module!");\n}\n\nTo use this module in main.rs, you need to do two things:
- \n
- Declare the module using the
modkeyword \n - Import the necessary items using
use\n
// main.rs\nmod greetings; // declare the module\n\nuse greetings::say_hello; // import the function\n\nfn main() {\n say_hello(); // use it\n}\n\nThat's it! Rust automatically looks for the file greetings.rs in the same folder where main.rs is located. If the file is found, the module is included.
Important: the say_hello function is marked as pub. If you forget pub, the compiler will say the function is private and inaccessible from outside. This is one of the most common mistakes beginners make.
Method 2: Module in a folder (mod.rs or lib.rs)
\n\nWhen your project grows, it's convenient to group modules into folders. For this, the file mod.rs is used inside the folder. It serves as the "entry point" for the module.
Let's create a folder utils/ and inside it mod.rs:
// utils/mod.rs\npub mod helpers; // declare a nested module\n\nNow let's create helpers.rs:
// utils/helpers.rs\npub fn do_something() {\n println!("Doing something useful");\n}\n\nIn main.rs, include it like this:
// main.rs\nmod utils; // declare the utils module (looks for utils/mod.rs)\n\nuse utils::helpers::do_something;\n\nfn main() {\n do_something();\n}\n\nNote: mod utils; tells Rust to look for utils/mod.rs or utils.rs. If it finds mod.rs — great, if it finds utils.rs — that works too. But you cannot have both files at the same time — the compiler will get confused.