The Manifest Format

The Cargo.toml file for each package is called its manifest. Every manifest file consists of the following sections:

The [package] section

The first section in a Cargo.toml is [package].

[package]
name = "hello_world" # the name of the package
version = "0.1.0"    # the current version, obeying semver
authors = ["Alice <a@example.com>", "Bob <b@example.com>"]

The only fields required by Cargo are name and version. If publishing to a registry, the registry may require additional fields. See the notes below and the publishing chapter for requirements for publishing to crates.io.

The name field

The package name is an identifier used to refer to the package. It is used when listed as a dependency in another package, and as the default name of inferred lib and bin targets.

The name must use only alphanumeric characters or - or _, and cannot be empty. Note that cargo new and cargo init impose some additional restrictions on the package name, such as enforcing that it is a valid Rust identifier and not a keyword. crates.io imposes even more restrictions, such as enforcing only ASCII characters, not a reserved name, not a special Windows name such as "nul", is not too long, etc.

The version field

Cargo bakes in the concept of Semantic Versioning, so make sure you follow some basic rules:

  • Before you reach 1.0.0, anything goes, but if you make breaking changes, increment the minor version. In Rust, breaking changes include adding fields to structs or variants to enums.
  • After 1.0.0, only make breaking changes when you increment the major version. Don’t break the build.
  • After 1.0.0, don’t add any new public API (no new pub anything) in patch-level versions. Always increment the minor version if you add any new pub structs, traits, fields, types, functions, methods or anything else.
  • Use version numbers with three numeric parts such as 1.0.0 rather than 1.0.

The authors field

The authors field lists people or organizations that are considered the "authors" of the package. The exact meaning is open to interpretation — it may list the original or primary authors, current maintainers, or owners of the package. These names will be listed on the crate's page on crates.io. An optional email address may be included within angled brackets at the end of each author.

Note: crates.io requires at least one author to be listed.

The edition field

You can opt in to a specific Rust Edition for your package with the edition key in Cargo.toml. If you don't specify the edition, it will default to 2015.

[package]
# ...
edition = '2018'

The edition key affects which edition your package is compiled with. Cargo will always generate packages via cargo new with the edition key set to the latest edition. Setting the edition key in [package] will affect all targets/crates in the package, including test suites, benchmarks, binaries, examples, etc.

The description field

The description is a short blurb about the package. crates.io will display this with your package. This should be plain text (not Markdown).

[package]
# ...
description = "A short description of my package"

Note: crates.io requires the description to be set.

The documentation field

The documentation field specifies a URL to a website hosting the crate's documentation. If no URL is specified in the manifest file, crates.io will automatically link your crate to the corresponding docs.rs page.

[package]
# ...
documentation = "https://docs.rs/bitflags"

The readme field

The readme field should be the path to a file in the package root (relative to this Cargo.toml) that contains general information about the package. This file will be transferred to the registry when you publish. crates.io will 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 named README.md, README.txt or README exists in the package root, then the name of that file will be used. You can suppress this behavior by setting this field to false. If the field is set to true, a default value of README.md will be assumed.

The homepage field

The homepage field should be a URL to a site that is the home page for your package.

[package]
# ...
homepage = "https://serde.rs/"

The repository field

The repository field should be a URL to the source repository for your package.

[package]
# ...
repository = "https://github.com/rust-lang/cargo/"

The license and license-file fields

The license field contains the name of the software license that the package is released under. The license-file field contains the path to a file containing the text of the license (relative to this Cargo.toml).

crates.io interprets the license field as an SPDX 2.1 license expression. The name must be a known license from the SPDX license list 3.6. Parentheses are not currently supported. See the SPDX site for more information.

SPDX license expressions support AND and OR operators to combine multiple licenses.1

[package]
# ...
license = "MIT OR Apache-2.0"

Using OR indicates the user may choose either license. Using AND indicates the user must comply with both licenses simultaneously. The WITH operator indicates a license with a special exception. Some examples:

  • MIT OR Apache-2.0
  • LGPL-2.1 AND MIT AND BSD-2-Clause
  • GPL-2.0+ WITH Bison-exception-2.2

If a package is using a nonstandard license, then the license-file field may be specified in lieu of the license field.

[package]
# ...
license-file = "LICENSE.txt"

Note: crates.io requires either license or license-file to be set.

1

Previously multiple licenses could be separated with a /, but that usage is deprecated.

The keywords field

The keywords field is an array of strings that describe this package. This can help when searching for the package on a registry, and you may choose any words that would help someone find this crate.

[package]
# ...
keywords = ["gamedev", "graphics"]

Note: crates.io has a maximum of 5 keywords. Each keyword must be ASCII text, start with a letter, and only contain letters, numbers, _ or -, and have at most 20 characters.

The categories field

The categories field is an array of strings of the categories this package belongs to.

categories = ["command-line-utilities", "development-tools::cargo-plugins"]

Note: crates.io has a maximum of 5 categories. Each category should match one of the strings available at https://crates.io/category_slugs, and must match exactly.

The workspace field

The workspace field can be used to configure the workspace that this package will be a member of. If not specified this will be inferred as the first Cargo.toml with [workspace] upwards in the filesystem. Setting this is useful 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 (contain package.workspace).

For more information, see the workspaces chapter.

The build field

The build field specifies a file in the package root which is a build script for building native code. More information can be found in the build script guide.

[package]
# ...
build = "build.rs"

The default is "build.rs", which loads the script from a file named build.rs in the root of the package. Use build = "custom_build_name.rs" to specify a path to a different file or build = false to disable automatic detection of the build script.

The links field

The links field specifies the name of a native library that is being linked to. More information can be found in the links section of the build script guide.

[package]
# ...
links = "foo"

The exclude and include fields

You can explicitly specify that a set of file patterns should be ignored or included for the purposes of packaging. The patterns specified in the exclude field identify a set of files that are not included, and the patterns in include specify files that are explicitly included.

The patterns should be gitignore-style patterns. Briefly:

  • foo matches any file or directory with the name foo anywhere in the package. This is equivalent to the pattern **/foo.
  • /foo matches any file or directory with the name foo only in the root of the package.
  • foo/ matches any directory with the name foo anywhere in the package.
  • Common glob patterns like *, ?, and [] are supported:
    • * matches zero or more characters except /. For example, *.html matches any file or directory with the .html extension anywhere in the package.
    • ? matches any character except /. For example, foo? matches food, but not foo.
    • [] allows for matching a range of characters. For example, [ab] matches either a or b. [a-z] matches letters a through z.
  • **/ prefix matches in any directory. For example, **/foo/bar matches the file or directory bar anywhere that is directly under directory foo.
  • /** suffix matches everything inside. For example, foo/** matches all files inside directory foo, including all files in subdirectories below foo.
  • /**/ matches zero or more directories. For example, a/**/b matches a/b, a/x/b, a/x/y/b, and so on.
  • ! prefix negates a pattern. For example, a pattern of src/**.rs and !foo.rs would match all files with the .rs extension inside the src directory, except for any file named foo.rs.

If git is being used for a package, the exclude field will be seeded with the gitignore settings from the repository.

[package]
# ...
exclude = ["build/**/*.o", "doc/**/*.html"]
[package]
# ...
include = ["src/**/*", "Cargo.toml"]

The options are mutually exclusive: setting include will override an exclude. Note that include must be an exhaustive list of files as otherwise necessary source files may not be included. The package's Cargo.toml is automatically included.

The include/exclude list is also used for change tracking in some situations. For targets built with rustdoc, it is used to determine the list of files to track to determine if the target should be rebuilt. If the package has a build script that does not emit any rerun-if-* directives, then the include/exclude list is used for tracking if the build script should be re-run if any of those files change.

The publish field

The publish field can be used to prevent a package from being published to a package registry (like crates.io) by mistake, for instance to keep a package private in a company.

[package]
# ...
publish = false

The value may also be an array of strings which are registry names that are allowed to be published to.

[package]
# ...
publish = ["some-registry-name"]

The metadata table

Cargo by default will warn about unused keys in Cargo.toml to assist in detecting typos and such. The package.metadata table, however, is completely ignored by Cargo and will not be warned about. This section can be used for tools which would like to store package configuration in Cargo.toml. For example:

[package]
name = "..."
# ...

# Metadata used when generating an Android APK, for example.
[package.metadata.android]
package-name = "my-awesome-android-app"
assets = "path/to/static"

There is a similar table at the workspace level at workspace.metadata. While cargo does not specify a format for the content of either of these tables, it is suggested that external tools may wish to use them in a consistent fashion, such as referring to the data in workspace.metadata if data is missing from package.metadata, if that makes sense for the tool in question.

The default-run field

The default-run field in the [package] section of the manifest can be used to specify a default binary picked by cargo run. For example, when there is both src/bin/a.rs and src/bin/b.rs:

[package]
default-run = "a"

The [badges] section

crates.io can display various badges for build status, test coverage, etc. for each crate. All badges are optional.

  • The badges pertaining to build status that are currently available are Appveyor, CircleCI, Cirrus CI, GitLab, Azure DevOps, Travis CI and Bitbucket Pipelines.
  • Available badges pertaining to code test coverage are Codecov and Coveralls.
  • There are also maintenance-related badges based on isitmaintained.com which state the issue resolution time, percent of open issues, and future maintenance intentions.

Most badge specifications require a repository key. It is expected to be in user/repo format.

[badges]

# Appveyor: `repository` is required. `branch` is optional; default is `master`
# `service` is optional; valid values are `github` (default), `bitbucket`, and
# `gitlab`; `id` is optional; you can specify the appveyor project id if you
# want to use that instead. `project_name` is optional; use when the repository
# name differs from the appveyor project name.
appveyor = { repository = "...", branch = "master", service = "github" }

# Circle CI: `repository` is required. `branch` is optional; default is `master`
circle-ci = { repository = "...", branch = "master" }

# Cirrus CI: `repository` is required. `branch` is optional; default is `master`
cirrus-ci = { repository = "...", branch = "master" }

# GitLab: `repository` is required. `branch` is optional; default is `master`
gitlab = { repository = "...", branch = "master" }

# Azure DevOps: `project` is required. `pipeline` is required. `build` is optional; default is `1`
# Note: project = `organization/project`, pipeline = `name_of_pipeline`, build = `definitionId`
azure-devops = { project = "...", pipeline = "...", build="2" }

# Travis CI: `repository` in format "<user>/<project>" is required.
# `branch` is optional; default is `master`
travis-ci = { repository = "...", branch = "master" }

# Bitbucket Pipelines: `repository` is required. `branch` is required
bitbucket-pipelines = { repository = "...", branch = "master" }

# Codecov: `repository` is required. `branch` is optional; default is `master`
# `service` is optional; valid values are `github` (default), `bitbucket`, and
# `gitlab`.
codecov = { repository = "...", branch = "master", service = "github" }

# Coveralls: `repository` is required. `branch` is optional; default is `master`
# `service` is optional; valid values are `github` (default) and `bitbucket`.
coveralls = { repository = "...", branch = "master", service = "github" }

# Is it maintained resolution time: `repository` is required.
is-it-maintained-issue-resolution = { repository = "..." }

# Is it maintained percentage of open issues: `repository` is required.
is-it-maintained-open-issues = { repository = "..." }

# Maintenance: `status` 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 the specifying dependencies page for information 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 as optimizations and debug settings. See the Profiles chapter for more detail.