1 Month Learning Rust - Packages, Crates, and Modules

1 Month Learning Rust - Packages, Crates, and Modules

Daily short news for you
  • For over a week now, I haven't posted anything, not because I have nothing to write about, but because I'm looking for ways to distribute more valuable content in this rapidly exploding AI era.

    As I shared earlier this year, the number of visitors to my blog is gradually declining. When I looked at the statistics, the number of users in the first six months of 2025 has dropped by 30% compared to the same period last year, and by 15% compared to the last six months of 2024. This indicates a reality that users are gradually leaving. What is the reason for this?

    I think the biggest reason is that user habits have changed. They primarily discover the blog through search engines, with Google being the largest. Almost half of the users return to the blog without going through the search step. This is a positive signal, but it's still not enough to increase the number of new users. Not to mention that now, Google has launched the AI Search Labs feature, which means AI displays summarized content when users search, further reducing the likelihood of users accessing the website. Interestingly, when Search Labs was introduced, English articles have taken over the rankings for the most accessed content.

    My articles are usually very long, sometimes reaching up to 2000 words. Writing such an article takes a lot of time. It's normal for many articles to go unread. I know and accept this because not everyone encounters the issues being discussed. For me, writing is a way to cultivate patience and thoughtfulness. Being able to help someone through my writing is a wonderful thing.

    Therefore, I am thinking of focusing on shorter and medium-length content to be able to write more. Long content will only be used when I want to write in detail or delve deeply into a particular topic. So, I am looking for ways to redesign the blog. Everyone, please stay tuned! 😄

    » Read more
  • CloudFlare has introduced the pay per crawl feature to charge for each time AI "crawls" data from your website. What does that mean 🤔?

    The purpose of SEO is to help search engines see the website. When users search for relevant content, your website appears in the search results. This is almost a win-win situation where Google helps more people discover your site, and in return, Google gets more users.

    Now, the game with AI Agents is different. AI Agents have to actively seek out information sources and conveniently "crawl" your data, then mix it up or do something with it that we can't even know. So this is almost a game that benefits only one side 🤔!?

    CloudFlare's move is to make AI Agents pay for each time they retrieve data from your website. If they don’t pay, then I won’t let them read my data. Something like that. Let’s wait a bit longer and see 🤓.

    » Read more
  • Continuing to update on the lawsuit between the Deno group and Oracle over the name JavaScript: It seems that Deno is at a disadvantage as the court has dismissed the Deno group's complaint. However, in August, they (Oracle) must be held accountable for each reason, acknowledging or denying the allegations presented by the Deno group in the lawsuit.

    JavaScript™ Trademark Update

    » Read more

Problem

In every programming language, there is something equally important - the package manager. Take JavaScript for example, it is already familiar with npm - a tool that allows you to download and share many useful libraries. Here, developers contribute and use packages to accelerate the product development process.

In Rust, cargo is a tool that functions similarly to npm, it also allows sharing and downloading packages, but the usage is somewhat different. Therefore, in today's article, we will explore the basic components, modules, and the cargo package manager together.

Packages and Crates

Rust provides two concepts, Crates and Packages, to unify the understanding. Simply put, a Crate is a single source file, while Packages are collections of multiple Crates.

cargo is the package manager integrated into Rust, it has similar functionality to Node's npm. This means that we can easily create, add, and remove packages.

The syntax to create a package:

$ cargo new my-project

A directory my-project is created, let's see what's inside it.

$ ls my-project
Cargo.toml
src

The src directory contains a main.rs file, which is the place for executable code. Cargo.toml stores various information about my-project such as its name, dependencies, similar to package.json in a JS/Node project.

To run the project, we use the command cargo run.

$ cargo run
   Compiling my-project v0.1.0 (/Users/hoaitx/my-project)
    Finished dev [unoptimized + debuginfo] target(s) in 0.81s
     Running `target/debug/my-project`
Hello, world!  

Modules

In JavaScript or Node.js, we can import/export modules using familiar syntax such as import/export or require, separating related logic into separate files for reusability. Rust has a similar concept, but with some significant differences.

To understand it simply, let's consider an .rs file as a module in Rust. When declaring a module mymodule in src/main.rs, it means that we are "declaring" to Rust that I will use this module...

pub mod mymodule;

fn main() {
    ...  
}

In this case, Rust will search for your mymodule in the following locations:

  • Inline, meaning within the same file where you declare the module (here it is main.rs).
  • In the file src/mymodule.rs (for newer Rust versions).
  • In the file src/mymodule/mod.rs (for older versions, still supported).

Suppose we write code for mymodule, let's go through each method.

  1. Inline
pub mod mymodule {
    pub fn hello() {
        println!("Hello, world!");
    }
}

fn main() {
    mymodule::hello();
}
  1. In the file src/mymodule.rs

File src/mymodule.rs:

pub fn hello() {
    println!("Hello, world!");
}

File src/main.rs

pub mod mymodule;

fn main() {
    mymodule::hello();
}

This declaration method may seem unfamiliar compared to regular JS/Node, where you export what you need and import what you use. In Rust, modules are "declared" for use, and Rust will automatically search for modules through the specified locations mentioned above.

We can also declare a module within another module. For example, adding a sub-module mysubmodule to src/mymodule.rs:

pub mod mysubmodule {
    pub fn sub_hello() {
        println!("Hello, world!");
    }
}

pub fn hello() {
    println!("Hello, world!");
}

Then in src/main.rs, we can use:

pub mod mymodule;

fn main() {
    mymodule::hello();
    mymodule::mysubmodule::sub_hello();
}

If you notice, you will see that the syntax to access sub-modules is ::, so the deeper the sub-modules, the longer the path. To simplify the code, Rust provides the use syntax to reduce code duplication.

In the file src/main.rs:

pub mod mymodule;

use mymodule::mysubmodule;

fn main() {
    mymodule::hello();
    mysubmodule::sub_hello();
}

use mymodule::mysubmodule has shortened the syntax for calling sub_hello(), and if you want to further shorten it, you can continue accessing sub-modules inside the use statement.

Modules can be declared using absolute or relative paths. Absolute paths start with crate, while relative paths do not. When using absolute paths, its starting position is from src, while with relative paths, it starts directly from the usage position.

mod front_of_house {
    pub mod hosting {
        fn add_to_waitlist() {}
    }
}

pub fn eat_at_restaurant() {
    // absolute path
    crate::front_of_house::hosting::add_to_waitlist();

    // relative path
    front_of_house::hosting::add_to_waitlist();
}

In the eat_at_restaurant function, there are two ways to call the add_to_waitlist function in the front_of_house modules. While the absolute path requires the additional crate declaration, making the code slightly longer compared to the relative path that starts directly from calling into the front_of_house modules. The choice between absolute and relative paths depends on each individual's workflow.

In relative paths, there is also the super syntax to "step back" and call a function in another module.

fn deliver_order() {}

mod back_of_house {
    fn fix_incorrect_order() {
        cook_order();
        super::deliver_order();
    }

    fn cook_order() {}
}

One interesting thing about modules in Rust is that modules declared from the beginning can be accessed throughout the project in different places. It's different from the import/export module syntax you might have seen in other programming languages. For example, in JavaScript, to call the same module in multiple places or files, we need to import it multiple times. But not in Rust.

To make it easier to understand, I will create another module named myothermodule in src/myothermodule.rs, and immediately we can call a function in src/mymodule.rs using super.

# file src/myothermodule.rs

pub fn call_mymodule() {
  super::mymodule::hello();
}

crates.io is the place to aggregate shared packages. You can search, read documentation, download, and use most shared packages here. For example, I want to use a package named rand above. There are two ways to install it:

  • Use the command cargo add rand.
  • Open Cargo.toml and add the name and version of the package under [dependencies]. Then use the cargo fetch command if your code editor does not automatically download the newly added package.

To use these packages, we don't need to declare modules but can directly use use. For example, calling a function that generates a random number in the range 1-100.

use rand::Rng;

fn main() {
    let secret_number = rand::thread_rng().gen_range(1..=100);
}
Premium
Hello

The secret stack of Blog

As a developer, are you curious about the technology secrets or the technical debts of this blog? All secrets will be revealed in the article below. What are you waiting for, click now!

As a developer, are you curious about the technology secrets or the technical debts of this blog? All secrets will be revealed in the article below. What are you waiting for, click now!

View all

Subscribe to receive new article notifications

or
* The summary newsletter is sent every 1-2 weeks, cancel anytime.

Comments (0)

Leave a comment...