Skip to content

Cargo — Rust's Package Manager & Build Tool

If you have used npm (or yarn/pnpm), Cargo will feel immediately familiar. It manages dependencies, builds your project, runs your code, and runs your tests — all under one roof.

Terminal window
# Node / TypeScript
mkdir my-app && cd my-app
npm init -y
npm install typescript --save-dev
# Rust
cargo new my-app # creates a binary (has fn main)
cargo new my-lib --lib # creates a library (no fn main)
cd my-app

cargo new creates:

flowchart TD
  root["my-app/"] --> toml["Cargo.toml — like package.json"]
  root --> lock["Cargo.lock — like package-lock.json"]
  root --> src["src/"]
  src --> main["main.rs — entry point"]
What cargo new creates
TypeScript
// package.json
{
"name": "my-app",
"version": "1.0.0",
"dependencies": {
"express": "^4.18.0"
},
"devDependencies": {
"typescript": "^5.0.0",
"@types/express": "^4.17.0"
}
}
Rust
# Cargo.toml
[package]
name = "my-app"
version = "0.1.0"
edition = "2021"
[dependencies]
axum = "0.7"
tokio = { version = "1", features = ["full"] }
serde = { version = "1", features = ["derive"] }
[dev-dependencies]
# test-only crates go here
Terminal window
# npm
npm install serde_json # runtime dep
npm install --save-dev vitest # dev dep
# Cargo
cargo add serde_json # runtime dep
cargo add --dev pretty_assertions # dev dep

cargo add updates Cargo.toml automatically, exactly like npm install.

Terminal window
cargo build # compile (debug, fast, unoptimized)
cargo build --release # compile (optimized, slower build)
cargo run # compile + execute
cargo run -- --port 8080 # pass args to your binary
cargo check # type-check only, no binary (very fast)
cargo test # run all tests
cargo test my_fn # run tests whose name contains "my_fn"
cargo doc --open # generate + open HTML docs
cargo clean # delete target/ directory
# Binary / application → COMMIT Cargo.lock (reproducible builds)
# Library crate → DO NOT commit Cargo.lock (let consumers pick versions)

This mirrors npm’s convention: applications commit package-lock.json; published libraries typically do not.

Which command adds a crate to your project (equivalent to `npm install <pkg>`)?
What does `cargo check` do differently from `cargo build`?
Should you commit Cargo.lock for a binary application?
Which file in Cargo is most similar to package.json?