The Manifest Format
TheCargo.toml file for each package is called itsmanifest. It is writtenin theTOML format. It contains metadata that is needed to compile the package. Checkoutthecargo locate-project section for more detail on how cargo finds the manifest file.
Every manifest file consists of the following sections:
cargo-features— Unstable, nightly-only features.[package]— Defines a package.name— The name of the package.version— The version of the package.authors— The authors of the package.edition— The Rust edition.rust-version— The minimal supported Rust version.description— A description of the package.documentation— URL of the package documentation.readme— Path to the package’s README file.homepage— URL of the package homepage.repository— URL of the package source repository.license— The package license.license-file— Path to the text of the license.keywords— Keywords for the package.categories— Categories of the package.workspace— Path to the workspace for the package.build— Path to the package build script.links— Name of the native library the package links with.exclude— Files to exclude when publishing.include— Files to include when publishing.publish— Can be used to prevent publishing the package.metadata— Extra settings for external tools.default-run— The default binary to run bycargo run.autolib— Disables library auto discovery.autobins— Disables binary auto discovery.autoexamples— Disables example auto discovery.autotests— Disables test auto discovery.autobenches— Disables bench auto discovery.resolver— Sets the dependency resolver to use.
- Target tables: (seeconfiguration for settings)
[lib]— Library target settings.[[bin]]— Binary target settings.[[example]]— Example target settings.[[test]]— Test target settings.[[bench]]— Benchmark target settings.
- Dependency tables:
[dependencies]— Package library dependencies.[dev-dependencies]— Dependencies for examples, tests, and benchmarks.[build-dependencies]— Dependencies for build scripts.[target]— Platform-specific dependencies.
[badges]— Badges to display on a registry.[features]— Conditional compilation features.[lints]— Configure linters for this package.[hints]— Provide hints for compiling this package.[patch]— Override dependencies.[replace]— Override dependencies (deprecated).[profile]— Compiler settings and optimizations.[workspace]— The workspace definition.
The[package] section
The first section in aCargo.toml is[package].
[package]name = "hello_world" # the name of the packageversion = "0.1.0" # the current version, obeying semverThe only field required by Cargo isname. If publishing toa registry, the registry may require additional fields. See the notes below andthe publishing chapter for requirements for publishing tocrates.io.
Thename field
The package name is an identifier used to refer to the package. It is usedwhen listed as a dependency in another package, and as the default name ofinferred lib and bin targets.
The name must use onlyalphanumeric characters or- or_, and cannot be empty.
Note thatcargo new andcargo init impose some additional restrictions onthe package name, such as enforcing that it is a valid Rust identifier and nota keyword.crates.io imposes even more restrictions, such as:
- Only ASCII characters are allowed.
- Do not use reserved names.
- Do not use special Windows names such as “nul”.
- Use a maximum of 64 characters of length.
Theversion field
Theversion field is formatted according to theSemVer specification:
Versions must have three numeric parts,the major version, the minor version, and the patch version.
A pre-release part can be added after a dash such as1.0.0-alpha.The pre-release part may be separated with periods to distinguish separatecomponents. Numeric components will use numeric comparison whileeverything else will be compared lexicographically.For example,1.0.0-alpha.11 is higher than1.0.0-alpha.4.
A metadata part can be added after a plus, such as1.0.0+21AF26D3.This is for informational purposes only and is generally ignored by Cargo.
Cargo bakes in the concept ofSemantic Versioning,so versions are consideredcompatible if their left-most non-zero major/minor/patch component is the same.See theResolver chapter for more information on how Cargo uses versions toresolve dependencies.
This field is optional and defaults to0.0.0. The field is required for publishing packages.
MSRV: Before 1.75, this field was required
Theauthors field
Warning: This field is deprecated
The optionalauthors field lists in an array the people or organizations that are consideredthe “authors” of the package. An optional email address may be included within angled brackets atthe end of each author entry.
[package]# ...authors = ["Graydon Hoare", "Fnu Lnu <no-reply@rust-lang.org>"]This field is surfaced in package metadata and in theCARGO_PKG_AUTHORSenvironment variable withinbuild.rs for backwards compatibility.
Theedition field
Theedition key is an optional key that affects whichRust Edition your packageis compiled with. Setting theedition key in[package] will affect alltargets/crates in the package, including test suites, benchmarks, binaries,examples, etc.
[package]# ...edition = '2024'Most manifests have theedition field filled in automatically bycargo newwith the latest stable edition. By defaultcargo new creates a manifest withthe 2024 edition currently.
If theedition field is not present inCargo.toml, then the 2015 edition isassumed for backwards compatibility. Note that all manifestscreated withcargo new will not use this historical fallback because theywill haveedition explicitly specified to a newer value.
Therust-version field
Therust-version field tells cargo what version of theRust toolchain you support for your package.Seethe Rust version chapter for more detail.
Thedescription field
The description is a short blurb about the package.crates.io will displaythis with your package. This should be plain text (not Markdown).
[package]# ...description = "A short description of my package"Note:crates.io requires the
descriptionto be set.
Thedocumentation field
Thedocumentation field specifies a URL to a website hosting the crate’sdocumentation. If no URL is specified in the manifest file,crates.io willautomatically link your crate to the correspondingdocs.rs page when thedocumentation has been built and is available (seedocs.rs queue).
[package]# ...documentation = "https://docs.rs/bitflags"Thereadme field
Thereadme field should be the path to a file in the package root (relativeto thisCargo.toml) that contains general information about the package.This file will be transferred to the registry when you publish.crates.iowill interpret it as Markdown and render it on the crate’s page.
[package]# ...readme = "README.md"If no value is specified for this field, and a file namedREADME.md,README.txt orREADME exists in the package root, then the name of thatfile will be used. You can suppress this behavior by setting this field tofalse. If the field is set totrue, a default value ofREADME.md willbe assumed.
Thehomepage field
Thehomepage field should be a URL to a site that is the home page for yourpackage.
[package]# ...homepage = "https://serde.rs"A value should only be set forhomepage if there is a dedicated website forthe crate other than the source repository or API documentation. Do not makehomepage redundant with either thedocumentation orrepository values.
Therepository field
Therepository field should be a URL to the source repository for yourpackage.
[package]# ...repository = "https://github.com/rust-lang/cargo"Thelicense andlicense-file fields
Thelicense field contains the name of the software license that the packageis released under. Thelicense-file field contains the path to a filecontaining the text of the license (relative to thisCargo.toml).
crates.io interprets thelicense field as anSPDX 2.3 licenseexpression. The name must be a known licensefrom theSPDX license list 3.20. See theSPDX sitefor more information.
SPDX license expressions support AND and OR operators to combine multiplelicenses.1
[package]# ...license = "MIT OR Apache-2.0"UsingOR indicates the user may choose either license. UsingAND indicatesthe user must comply with both licenses simultaneously. TheWITH operatorindicates a license with a special exception. Some examples:
MIT OR Apache-2.0LGPL-2.1-only AND MIT AND BSD-2-ClauseGPL-2.0-or-later WITH Bison-exception-2.2
If a package is using a nonstandard license, then thelicense-file field maybe specified in lieu of thelicense field.
[package]# ...license-file = "LICENSE.txt"Note:crates.io requires either
licenseorlicense-fileto be set.
Thekeywords field
Thekeywords field is an array of strings that describe this package. Thiscan help when searching for the package on a registry, and you may choose anywords that would help someone find this crate.
[package]# ...keywords = ["gamedev", "graphics"]Note:crates.io allows a maximum of 5 keywords. Each keyword must beASCII text, have at most 20 characters, start with an alphanumeric character,and only contain letters, numbers,
_,-or+.
Thecategories field
Thecategories field is an array of strings of the categories this packagebelongs to.
categories = ["command-line-utilities", "development-tools::cargo-plugins"]Note:crates.io has a maximum of 5 categories. Each category shouldmatch one of the strings available athttps://crates.io/category_slugs, andmust match exactly.
Theworkspace field
Theworkspace field can be used to configure the workspace that this packagewill be a member of. If not specified this will be inferred as the firstCargo.toml with[workspace] upwards in the filesystem. Setting this isuseful if the member is not inside a subdirectory of the workspace root.
[package]# ...workspace = "path/to/workspace/root"This field cannot be specified if the manifest already has a[workspace]table defined. That is, a crate cannot both be a root crate in a workspace(contain[workspace]) and also be a member crate of another workspace(containpackage.workspace).
For more information, see theworkspaces chapter.
Thebuild field
Thebuild field specifies a file in the package root which is abuildscript for building native code. More information can be found in thebuildscript guide.
[package]# ...build = "build.rs"The default is"build.rs", which loads the script from a file namedbuild.rs in the root of the package. Usebuild = "custom_build_name.rs" tospecify a path to a different file orbuild = false to disable automaticdetection of the build script.
Thelinks field
Thelinks field specifies the name of a native library that is being linkedto. More information can be found in thelinks section of the buildscript guide.
For example, a crate that links a native library called “git2” (e.g.libgit2.aon Linux) may specify:
[package]# ...links = "git2"Theexclude andinclude fields
Theexclude andinclude fields can be used to explicitly specify whichfiles are included when packaging a project to bepublished,and certain kinds of change tracking (described below).The patterns specified in theexclude field identify a set of files that arenot included, and the patterns ininclude specify files that are explicitlyincluded.You may runcargo package --list to verify which files willbe included in the package.
[package]# ...exclude = ["/ci", "images/", ".*"][package]# ...include = ["/src", "COPYRIGHT", "/examples", "!/examples/big_example"]The default if neither field is specified is to include all files from theroot of the package, except for the exclusions listed below.
Ifinclude is not specified, then the following files will be excluded:
- If the package is not in a git repository, all “hidden” files starting witha dot will be skipped.
- If the package is in a git repository, any files that are ignored by thegitignore rules of the repository and global git configuration will beskipped.
Regardless of whetherexclude orinclude is specified, the following filesare always excluded:
- Any sub-packages will be skipped (any subdirectory that contains a
Cargo.tomlfile). - A directory named
targetin the root of the package will be skipped.
The following files are always included:
- The
Cargo.tomlfile of the package itself is always included, it does notneed to be listed ininclude. - A minimized
Cargo.lockis automatically included.Seecargo packagefor more information. - If a
license-fileis specified, itis always included.
The options are mutually exclusive; settinginclude will override anexclude. If you need to have exclusions to a set ofinclude files, use the! operator described below.
The patterns should begitignore-style patterns. Briefly:
foomatches any file or directory with the namefooanywhere in thepackage. This is equivalent to the pattern**/foo./foomatches any file or directory with the namefooonly in the root ofthe package.foo/matches anydirectory with the namefooanywhere in the package.- Common glob patterns like
*,?, and[]are supported:*matches zero or more characters except/. For example,*.htmlmatches any file or directory with the.htmlextension anywhere in thepackage.?matches any character except/. For example,foo?matchesfood,but notfoo.[]allows for matching a range of characters. For example,[ab]matches eitheraorb.[a-z]matches letters a through z.
**/prefix matches in any directory. For example,**/foo/barmatches thefile or directorybaranywhere that is directly under directoryfoo./**suffix matches everything inside. For example,foo/**matches allfiles inside directoryfoo, including all files in subdirectories belowfoo./**/matches zero or more directories. For example,a/**/bmatchesa/b,a/x/b,a/x/y/b, and so on.!prefix negates a pattern. For example, a pattern ofsrc/*.rsand!foo.rswould match all files with the.rsextension inside thesrcdirectory, except for any file namedfoo.rs.
The include/exclude list is also used for change tracking in some situations.For targets built withrustdoc, it is used to determine the list of files totrack to determine if the target should be rebuilt. If the package has abuild script that does not emit anyrerun-if-* directives, then theinclude/exclude list is used for tracking if the build script should be re-runif any of those files change.
Thepublish field
Thepublish field can be used to control which registries names the packagemay be published to:
[package]# ...publish = ["some-registry-name"]To prevent a package from being published to a registry (like crates.io) by mistake,for instance to keep a package private in a company,you can omit theversion field.If you’d like to be more explicit, you can disable publishing:
[package]# ...publish = falseIf publish array contains a single registry,cargo publish command will useit when--registry flag is not specified.
Themetadata table
Cargo by default will warn about unused keys inCargo.toml to assist indetecting typos and such. Thepackage.metadata table, however, is completelyignored by Cargo and will not be warned about. This section can be used fortools which would like to store package configuration inCargo.toml. Forexample:
[package]name = "..."# ...# Metadata used when generating an Android APK, for example.[package.metadata.android]package-name = "my-awesome-android-app"assets = "path/to/static"You’ll need to look in the documentation for your tool to see how to use this field.For Rust Projects that usepackage.metadata tables, see:
There is a similar table at the workspace level atworkspace.metadata. While cargo does not specify aformat for the content of either of these tables, it is suggested thatexternal tools may wish to use them in a consistent fashion, such as referringto the data inworkspace.metadata if data is missing frompackage.metadata,if that makes sense for the tool in question.
Thedefault-run field
Thedefault-run field in the[package] section of the manifest can be usedto specify a default binary picked bycargo run. For example, when there isbothsrc/bin/a.rs andsrc/bin/b.rs:
[package]default-run = "a"The[lints] section
Override the default level of lints from different tools by assigning them to a new level in atable, for example:
[lints.rust]unsafe_code = "forbid"This is short-hand for:
[lints.rust]unsafe_code = { level = "forbid", priority = 0 }level corresponds to thelint levels inrustc:
forbiddenywarnallow
priority is a signed integer that controls which lints or lint groups override other lint groups:
- lower (particularly negative) numbers have lower priority, being overriddenby higher numbers, and show up first on the command-line to tools like
rustc
To know which table under[lints] a particular lint belongs under, it is the part before:: in the lintname. If there isn’t a::, then the tool isrust. For example a warningaboutunsafe_code would belints.rust.unsafe_code but a lint aboutclippy::enum_glob_use would belints.clippy.enum_glob_use.
For example:
[lints.rust]unsafe_code = "forbid"[lints.clippy]enum_glob_use = "deny"Generally, these will only affect local development of the current package.Cargo only applies these to the current package and not to dependencies.As for dependents, Cargo suppresses lints from non-path dependencies with features like--cap-lints.
MSRV: Respected as of 1.74
The[hints] section
The[hints] section allows specifying hints for compiling this package. Cargowill respect these hints by default when compiling this package, though thetop-level package being built can override these values through the[profile]mechanism. Hints are, by design, always safe for Cargo to ignore; if Cargoencounters a hint it doesn’t understand, or a hint it understands but with avalue it doesn’t understand, it will warn, but not error. As a result,specifying hints in a crate does not impact the MSRV of the crate.
Individual hints may have an associated unstable feature gate that you need topass in order to apply the configuration they specify, but if you don’t specifythat unstable feature gate, you will again get only a warning, not an error.
There are no stable hints at this time. See thehint-mostly-unuseddocumentation for informationon an unstable hint.
MSRV: Respected as of 1.90.
The[badges] section
The[badges] section is for specifying status badges that can be displayedon a registry website when the package is published.
Note:crates.io previously displayed badges next to a crate on itswebsite, but that functionality has been removed. Packages should placebadges in its README file which will be displayed oncrates.io (seethe
readmefield).
[badges]# The `maintenance` table indicates the status of the maintenance of# the crate. This may be used by a registry, but is currently not# used by crates.io. See https://github.com/rust-lang/crates.io/issues/2437# and https://github.com/rust-lang/crates.io/issues/2438 for more details.## The `status` field is required. Available options are:# - `actively-developed`: New features are being added and bugs are being fixed.# - `passively-maintained`: There are no plans for new features, but the maintainer intends to# respond to issues that get filed.# - `as-is`: The crate is feature complete, the maintainer does not intend to continue working on# it or providing support, but it works for the purposes it was designed for.# - `experimental`: The author wants to share it with the community but is not intending to meet# anyone's particular use case.# - `looking-for-maintainer`: The current maintainer would like to transfer the crate to someone# else.# - `deprecated`: The maintainer does not recommend using this crate (the description of the crate# can describe why, there could be a better solution available or there could be problems with# the crate that the author does not want to fix).# - `none`: Displays no badge on crates.io, since the maintainer has not chosen to specify# their intentions, potential crate users will need to investigate on their own.maintenance = { status = "..." }Dependency sections
See thespecifying dependencies page forinformation on the[dependencies],[dev-dependencies],[build-dependencies], and target-specific[target.*.dependencies] sections.
The[profile.*] sections
The[profile] tables provide a way to customize compiler settings such asoptimizations and debug settings. Seethe Profiles chapter formore detail.
Previously multiple licenses could be separated with a
/, but thatusage is deprecated.↩