Skip to content

We are working on this site. Want to help? Open an issue or a pull request on GitHub.

Hello, Cargo!

Cargo is Rust’s package manager and build system. It’s similar to npm or yarn in the JavaScript ecosystem, but with additional features for building and testing your code.

If you’re coming from JavaScript, you’re probably familiar with package managers like npm or yarn. Cargo serves a similar purpose, but it’s even more central to the Rust ecosystem:

  • Dependency Management: Like npm, Cargo downloads and manages your project’s dependencies
  • Build System: Cargo compiles your code, similar to webpack or other build tools
  • Task Runner: Cargo can run tests, generate documentation, and publish packages

Instead of manually creating files like we did in the previous section, let’s use Cargo to create a new project:

cargo new hello_cargo
cd hello_cargo

This is similar to npm init or yarn init in JavaScript, but it actually creates more initial files.

Let’s look at what Cargo created:

hello_cargo/
├── Cargo.toml
└── src/
    └── main.rs

This is similar to a JavaScript project structure:

RustJavaScriptPurpose
Cargo.tomlpackage.jsonProject configuration and dependencies
src/src/Source code directory
target/ (created later)node_modules/Build artifacts and dependencies

Open Cargo.toml and you’ll see something like:

[package]
name = "hello_cargo"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]

This is similar to a package.json file in JavaScript:

  • [package] contains metadata about your project
  • [dependencies] is where you’ll list external libraries (called “crates” in Rust)

Now, look at src/main.rs:

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

Cargo created a “Hello, world!” program for us automatically.

Cargo provides commands for building and running your project:

cargo build

This creates an executable in target/debug/hello_cargo (or target\debug\hello_cargo.exe on Windows).

This is similar to using a build script in a JavaScript project, but more standardized.

You can run the built executable directly, or use:

cargo run

This will build (if necessary) and then run your program in one step. It’s similar to npm start or yarn start in JavaScript projects.

If you want to check your code compiles without producing an executable:

cargo check

This is faster than cargo build and useful during development, similar to using a linter in JavaScript.

When you’re ready to release your program, use:

cargo build --release

This creates an optimized executable in target/release/ instead of target/debug/.

This is similar to the difference between development and production builds in JavaScript bundlers like webpack.

Cargo Commandnpm/yarn EquivalentPurpose
cargo newnpm init/yarn initCreate a new project
cargo buildnpm run buildBuild the project
cargo runnpm startBuild and run the project
cargo testnpm testRun tests
cargo addnpm install/yarn addAdd a dependency
cargo docN/A (JSDoc)Generate documentation
cargo publishnpm publishPublish to registry

To add dependencies to your project, you can either:

  1. Manually edit Cargo.toml:
[dependencies]
ferris-says = "0.2"
  1. Or use the cargo add command (similar to npm install/yarn add):
cargo add ferris-says

After adding a dependency, run cargo build to download and compile it.

To update your dependencies:

cargo update

This is similar to npm update or yarn upgrade.

Let’s modify our program to use an external crate. Edit src/main.rs:

use ferris_says::say;
use std::io::{stdout, BufWriter};

fn main() {
    let stdout = stdout();
    let message = String::from("Hello fellow Rustaceans!");
    let width = message.chars().count();
    
    let mut writer = BufWriter::new(stdout.lock());
    say(message.as_str(), width, &mut writer).unwrap();
}

Now run the program:

cargo run

You should see a message from Ferris, the unofficial Rust mascot:

----------------------------
< Hello fellow Rustaceans! >
----------------------------
              \
               \
                 _~^~^~_
             \) /  o o  \ (/
               '_   -   _'
               / '-----' \

After building your project, you’ll notice a new file called Cargo.lock. This is similar to package-lock.json or yarn.lock in JavaScript projects. It records the exact versions of dependencies that were used so your builds are reproducible.

Cargo is a powerful tool that combines:

  • Package management (like npm/yarn)
  • Build system (like webpack)
  • Test runner (like Jest)
  • Documentation generator
  • Publishing tool

In the JavaScript ecosystem, these functions are often split across multiple tools, but Cargo brings them all together in one cohesive package.

Now that you understand the basics of Cargo, let’s move on to building a more substantial program that will give you a better feel for Rust’s syntax and features.