Rust Development Environment

cargo run

cargo run (aliased as cargo r) compiles the current package's executable binary (if any source files or dependencies have changed since the last build) and immediately executes the resulting binary in the current working directory.

How cargo run Works

Running cargo run combines cargo build and binary execution into a single step:

User runs `cargo run -- arg1 arg2`
       │
       ├──> 1. Checks if `target/debug/<bin>` is up to date (recompiles if needed)
       │
       └──> 2. Executes `target/debug/<bin> arg1 arg2` with current working directory preserved
cargo run
   Compiling my_project v0.1.0 (/Users/username/my_project)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.19s
     Running `target/debug/my_project`
Hello, world!

When you invoke cargo run, the spawned process inherits your current working directory (the directory where you typed cargo run, not target/debug/). Relative file paths opened inside your Rust program (such as std::fs::read_to_string("data.txt")) resolve relative to the directory from which you ran cargo run.

Passing Command-Line Arguments (--)

Because both cargo run and your own program can accept command-line flags (such as -v, --help, or --release), Cargo uses a double dash (--) to separate Cargo options from your program's arguments:

cargo run --release --bin worker -- --threads 4 --input jobs.json
          ──────────────────────    ─────────────────────────────
                    │                             │
      Interpreted by `cargo run`       Passed to `worker` (`std::env::args()`)
// src/main.rs
fn main() {
    let args: Vec<String> = std::env::args().skip(1).collect();
    println!("Received {} argument(s): {args:?}", args.len());
}
cargo run -q -- --threads 4 --input jobs.json
Received 4 argument(s): ["--threads", "4", "--input", "jobs.json"]

Note: If you forget the -- separator and write cargo run --help, Cargo prints the help page for cargo run itself rather than running your binary with --help. Always write cargo run -- --help to pass --help to your program.

Selecting Which Binary or Example to Run

A Cargo package can contain multiple runnable targets (src/main.rs, files in src/bin/*.rs, and files in examples/*.rs). Use --bin or --example to choose which target cargo run launches:

Command Target Executed
cargo run Runs the default binary (src/main.rs, or the target named in default-run in Cargo.toml)
cargo run --bin <name> Compiles and runs src/bin/<name>.rs (or src/bin/<name>/main.rs)
cargo run --example <name> Compiles and runs examples/<name>.rs
cargo run -p <pkg> Runs the default binary of member package <pkg> inside a Cargo workspace
cargo run --release / -r Compiles with optimizations (release profile) and runs target/release/<name>
cargo run --quiet / -q Suppresses Cargo's Compiling / Finished / Running status lines

Common Errors

Running cargo run on a Library-Only Package

If a package has src/lib.rs and no src/main.rs or src/bin/*.rs, cargo run has no executable entry point to launch:

error: a bin target must be available for `cargo run`

Use cargo test to run a library's unit and documentation tests, or create an example program in examples/demo.rs and run it with cargo run --example demo.

Multiple Binaries Without default-run

When a package defines both src/main.rs and one or more files in src/bin/, running bare cargo run without --bin <name> produces an ambiguity prompt:

error: `cargo run` could not determine which binary to run. Use the `--bin` option to specify a binary, or the `default-run` manifest key.
available binaries: cli, migrate, server

Either specify cargo run --bin cli on the command line or add default-run = "cli" under [package] in Cargo.toml.