Cargo.toml Builder (Rust)

Generate a Cargo.toml for a Rust library or binary project

Build a Cargo.toml with package metadata, edition, a dependencies section of common crates (serde, tokio, reqwest, axum, clap), dev-dependencies and a release profile for a Rust lib or binary. It runs free in your browser on Gera Tools, with nothing uploaded.

Last updated Source: Gera Tools

How does Cargo interpret a version like "1.0"?

By default a bare version string is a caret requirement, so 1.0 means at least 1.0.0 but below 2.0.0. Cargo picks the newest compatible release and records the exact choice in Cargo.lock. Use an explicit operator like =1.0.3 only when you need to freeze a single version.

The Cargo.toml Builder generates the manifest at the heart of every Rust project. Choose whether you are building a binary or a library, pick the crates you need, and the tool emits a complete [package], [dependencies], [dev-dependencies] and release profile.

How it works

[package] holds the crate name, version, edition, authors and license. The target section is either [[bin]] (an executable from src/main.rs) or [lib] (a reusable library from src/lib.rs). [dependencies] lists each crate you selected, using Cargo’s table syntax when features are needed — for example serde is emitted as serde = { version = "1.0", features = ["derive"] } so the derive macros are enabled.

Cargo treats a bare version string as a caret requirement: "1.0" resolves to any 1.x release at or above 1.0.0. The exact versions Cargo actually selects are written to Cargo.lock on first build, which is what makes builds reproducible.

What each crate does

Understanding why a dependency belongs in your project saves you from over-fetching. Here is a brief description of each offered crate:

CratePurpose
serdeSerialization and deserialization framework; with the derive feature it generates Serialize/Deserialize impls automatically
tokioAsync runtime; the full feature enables timers, I/O, net, process, and the #[tokio::main] macro
reqwestHTTP client built on tokio; handles TLS, redirects, JSON, and multipart
axumLightweight, type-safe HTTP router and server from the tokio project
clapDerives a CLI from a struct; the derive feature lets you annotate fields for flags, arguments, and subcommands
anyhowErgonomic error handling; anyhow::Result wraps any error with context without requiring custom error types
tracingStructured, levelled logging compatible with async; pair with tracing-subscriber for output formatting

Example

After saving the manifest, build to lock dependencies:

cargo build           # resolves versions, writes Cargo.lock
cargo build --release # optimized build using [profile.release]

A minimal async binary manifest looks like this:

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

[[bin]]
name = "myapp"
path = "src/main.rs"

[dependencies]
tokio = { version = "1", features = ["full"] }
anyhow = "1"

[profile.release]
lto = true
codegen-units = 1

Tips and common mistakes

Keep test crates in dev-dependencies. Crates like criterion and tokio-test only belong there; putting them in [dependencies] means every downstream user of your library compiles them unnecessarily.

Commit Cargo.lock for binaries, not libraries. Locking exact versions in a binary ensures reproducible builds across machines. For libraries, leaving it out lets downstream projects pick the newest compatible versions across their own dependency tree.

Features cost compile time. tokio = { version = "1", features = ["full"] } is convenient but pulls in everything. In production, prefer listing only the features you actually use — rt-multi-thread, net, time — to shorten build times.

The release profile is opt-in. lto = true and codegen-units = 1 produce faster, smaller executables but slow down the release compile significantly. They do not affect cargo build (debug) at all, so leave them enabled for final artefacts.