Cargo.toml Configuration

How to configure the Rust project manifest (Cargo.toml) for Tauri v2 – from project metadata and dependency management to build profile tuning.

Cargo.toml is the manifest for the Rust side of your Tauri application. While tauri.conf.json controls windows, bundles, and security, Cargo.toml defines what your Rust code compiles against: the crate’s identity, the libraries it depends on, and the profiles that shape how the final binary is built. The Tauri scaffolding (create-tauri-app) generates a working Cargo.toml for you, but you’ll need to touch it whenever you add a plugin, adjust performance settings, or prepare your app for distribution.

Project Information

The [package] section holds metadata that identifies your crate and eventually feeds into the bundled application. Most fields are standard Rust fare, but a few have direct consequences for your Tauri build.

[package]
name = "my-tauri-app"
version = "0.1.0"
edition = "2021"
description = "A desktop tool for daily notes"
authors = ["You <you@example.com>"]
license = "MIT"
repository = "https://github.com/yourname/my-tauri-app"

name becomes the binary that cargo build produces. It should be a valid crate identifier — lowercase alphanumeric, hyphens, and underscores. The Tauri bundler uses the same name for the output executable unless you override it in tauri.conf.json, so keeping the two consistent avoids surprises when you hand the app to someone else.

version sets the Rust crate version, but Tauri’s bundler also reads this as the application version if tauri.conf.json version is not explicitly set. Updating both together, or setting the product version in tauri.conf.json, makes it clear which number a user sees versus the internal package version.

Edition must be 2021 or later:

Tauri v2 requires at least Rust 1.70 and expects the edition key to be "2021". Using edition = "2018" causes compilation errors because Tauri’s procedural macros depend on syntax introduced in the 2021 edition. The scaffolding always sets this correctly; only old or hand-crafted projects might need the fix.

The remaining keys — description, authors, license, repository — don’t affect the build, but they make your project self-documenting and are used when you publish the crate to a registry. For a private desktop app, they’re optional but helpful for any teammate who opens the workspace.

Dependency Management

Dependencies determine what Tauri features are available at runtime and how your backend Rust code talks to the frontend. A Tauri v2 project always has at least two dependency tables: [dependencies] for the final binary and [build-dependencies] for the build script that embeds the frontend assets.

[dependencies]
tauri = { version = "2", features = ["devtools"] }
tauri-plugin-shell = "2"
tauri-plugin-fs = "2"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
[build-dependencies]
tauri-build = { version = "2", features = [] }

The Tauri runtime crate

tauri is the core. Without it you have no window, no IPC, and no application loop. The features key enables built-in functionality that is not yet a separate plugin. For example, "devtools" activates developer tools in debug builds, while "tray-icon" and "global-shortcut" add tray and hotkey support directly from the runtime. In Tauri v2, the recommended pattern is to use dedicated plugin crates for capabilities like shell access or filesystem access. The runtime crate itself is kept lean.

Plugin crates

Plugins are packaged as separate crates. To let your app open a URL or run a system command, you add tauri-plugin-shell; to read or write files, you add tauri-plugin-fs. Each plugin crate must match the major version of the Tauri runtime — all tauri-* crates in the tree need to use version "2". Adding the crate to [dependencies] is only step one; you also need to register the plugin in your Rust setup code and grant the required permissions in a capability file.

Never mix Tauri major versions:

If you add tauri-plugin-shell = "1" while the tauri crate is "2", compilation will fail with mismatched trait and type errors. The APIs between v1 and v2 are incompatible. Before adding any plugin, check that its latest major version targets Tauri v2.

Build dependency

tauri-build lives under [build-dependencies]. It is called during cargo build to generate the code that loads your frontend assets and sets up the application context. Without it, Tauri cannot find your UI files. It’s always version "2" and rarely needs extra features.

Other Rust dependencies

You’ll often pull in helper crates like serde for serialization or reqwest for HTTP requests. These follow the same TOML syntax:

[dependencies]
reqwest = { version = "0.12", features = ["json"] }

Versioning works with standard Cargo semver rules: "0.12" means >=0.12.0, <0.13.0. A caret ^ is implied; a tilde ~ restricts updates to the same minor version. For local plugins still under development, you can use a path dependency:

[dependencies]
my-tauri-plugin = { path = "../my-tauri-plugin" }

Git dependencies are also allowed when you need an unreleased fix:

[dependencies]
tauri-plugin-sql = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2" }

Lock file keeps builds reproducible:

Cargo.lock records the exact versions that were resolved. Commit it to version control so that every contributor and CI pipeline builds against the same dependency set. This is especially important for release builds where you don’t want a silent patch version change.

Build Profiles

Cargo has two default profiles: dev for cargo build (fast, unoptimized) and release for cargo build --release (slow, fully optimized). Tauri scaffolds a custom [profile.release] that favours small, fast binaries — exactly what you want for an installer that users download.

[profile.release]
panic = "abort"
codegen-units = 1
lto = true
opt-level = "s"
strip = true

Each key represents a deliberate trade-off:

  • panic = "abort" — the process terminates immediately on a panic instead of unwinding the stack. This removes the unwinding tables from the binary and simplifies dependency code, resulting in a smaller file.
  • codegen-units = 1 — Cargo compiles all crates as a single unit rather than splitting them across parallel jobs. This gives the optimizer more visibility and produces a tighter final binary, at the cost of longer compile times.
  • lto = true — enables link-time optimization. The compiler performs whole-program analysis and can inline functions across crate boundaries. It is one of the most effective size-reduction techniques, but it can multiply build duration by a factor of two or more.
  • opt-level = "s" — optimise for size. The compiler applies a set of transformations that favour binary footprint over raw speed. For a desktop application with a webview frontend, this is usually the right balance; pure speed improvements in the Rust backend are often imperceptible. If you need absolute minimum size, "z" applies further size optimisations.
  • strip = true — removes debug symbols from the binary. This shaves off a significant amount of bytes and should always be enabled for distribution unless you need to debug a release build.

Verifying your release profile:

Run cargo build --release and check the output in src-tauri/target/release/. A minimal Tauri application with these settings often produces a binary in the 3–5 MB range. If your binary is closer to 20 MB, double-check that strip and lto are enabled — missing either one leaves a lot of dead weight in the executable.

LTO dramatically slows down builds:

During active development, release builds with LTO can take several minutes. For a quick sanity check before deployment, you can temporarily comment out lto to get faster turnaround. Just remember to re-enable it for your final distribution build.

The default dev profile is purposely left unchanged: no optimisations, full debug symbols, fast incremental compilation. If you ever need to profile a dev build, you can override specific keys under [profile.dev], but Tauri’s debugging experience relies on unoptimised code for accurate source maps and hot-reload.


Project Information

Learn how to configure project metadata in Cargo.toml for your Tauri application, covering name, version, edition, authors, and license fields.

Dependency Management in Cargo.toml

Learn how to handle Rust crate dependencies, feature flags, optional crates, and workspace settings inside the Cargo.toml manifest of a Tauri v2 project.

Build Profiles in Cargo.toml

Learn how to configure compiler settings for development and release builds using Cargo profiles, and optimize your Tauri app binary size and performance.