Publishing on crates.io

Once you've got a library that you'd like to share with the world, it's time topublish it on crates.io! Publishing a crate is when a specificversion is uploaded to be hosted on crates.io.

Take care when publishing a crate, because a publish is permanent. Theversion can never be overwritten, and the code cannot be deleted. There is nolimit to the number of versions which can be published, however.

Before your first publish

First thing’s first, you’ll need an account on crates.io to acquirean API token. To do so, visit the home page and log in via a GitHubaccount (required for now). After this, visit your AccountSettings page and run the cargo login commandspecified.

  1. $ cargo login abcdefghijklmnopqrstuvwxyz012345

This command will inform Cargo of your API token and store it locally in your~/.cargo/credentials. Note that this token is a secret and should not beshared with anyone else. If it leaks for any reason, you should regenerate itimmediately.

Before publishing a new crate

Keep in mind that crate names on crates.io are allocated on a first-come-first-serve basis. Once a crate name is taken, it cannot be used for another crate.

Check out the metadata you canspecify in Cargo.toml to ensureyour crate can be discovered more easily! Before publishing, make sure you havefilled out the following fields:

  • authors
  • license or license-file
  • description
  • homepage
  • documentation
  • repositoryIt would also be a good idea to include some keywords and categories,though they are not required.

If you are publishing a library, you may also want to consult the Rust APIGuidelines.

Packaging a crate

The next step is to package up your crate and upload it to crates.io. Forthis we’ll use the cargo publish subcommand. This command performs the followingsteps:

  • Perform some verification checks on your package.
  • Compress your source code into a .crate file.
  • Extract the .crate file into a temporary directory and verify that itcompiles.
  • Upload the .crate file to crates.io.
  • The registry will perform some additional checks on the uploaded packagebefore adding it.It is recommended that you first run cargo publish —dry-run (or cargo package which is equivalent) to ensure there aren't any warnings or errorsbefore publishing. This will perform the first three steps listed above.
  1. $ cargo publish --dry-run

You can inspect the generated .crate file in the target/package directory.crates.io currently has a 10MB size limit on the .crate file. You may wantto check the size of the .crate file to ensure you didn't accidentallypackage up large assets that are not required to build your package, such astest data, website documentation, or code generation. You can check whichfiles are included with the following command:

  1. $ cargo package --list

Cargo will automatically ignore files ignored by your version control systemwhen packaging, but if you want to specify an extra set of files to ignore youcan use the excludekey in themanifest:

  1. [package]
  2. # ...
  3. exclude = [
  4. "public/assets/*",
  5. "videos/*",
  6. ]

If you’d rather explicitly list the files to include, Cargo also supports aninclude key, which if set, overrides the exclude key:

  1. [package]
  2. # ...
  3. include = [
  4. "**/*.rs",
  5. "Cargo.toml",
  6. ]

Uploading the crate

When you are ready to publish, use the cargo publish commandto upload to crates.io:

  1. $ cargo publish

And that’s it, you’ve now published your first crate!

Publishing a new version of an existing crate

In order to release a new version, change the version value specified inyour Cargo.toml manifest. Keep in mind the semverrules, and consult RFC 1105 forwhat constitutes a semver-breaking change. Then run cargo publish asdescribed above to upload the new version.

Managing a crates.io-based crate

Management of crates is primarily done through the command line cargo toolrather than the crates.io web interface. For this, there are a few subcommandsto manage a crate.

cargo yank

Occasions may arise where you publish a version of a crate that actually ends upbeing broken for one reason or another (syntax error, forgot to include a file,etc.). For situations such as this, Cargo supports a “yank” of a version of acrate.

  1. $ cargo yank --vers 1.0.1
  2. $ cargo yank --vers 1.0.1 --undo

A yank does not delete any code. This feature is not intended for deletingaccidentally uploaded secrets, for example. If that happens, you must resetthose secrets immediately.

The semantics of a yanked version are that no new dependencies can be createdagainst that version, but all existing dependencies continue to work. One of themajor goals of crates.io is to act as a permanent archive of crates that doesnot change over time, and allowing deletion of a version would go against thisgoal. Essentially a yank means that all packages with a Cargo.lock will notbreak, while any future Cargo.lock files generated will not list the yankedversion.

cargo owner

A crate is often developed by more than one person, or the primary maintainermay change over time! The owner of a crate is the only person allowed to publishnew versions of the crate, but an owner may designate additional owners.

  1. $ cargo owner --add my-buddy
  2. $ cargo owner --remove my-buddy
  3. $ cargo owner --add github:rust-lang:owners
  4. $ cargo owner --remove github:rust-lang:owners

The owner IDs given to these commands must be GitHub user names or GitHub teams.

If a user name is given to —add, that user is invited as a “named” owner, withfull rights to the crate. In addition to being able to publish or yank versionsof the crate, they have the ability to add or remove owners, including theowner that made them an owner. Needless to say, you shouldn’t make people youdon’t fully trust into a named owner. In order to become a named owner, a usermust have logged into crates.io previously.

If a team name is given to —add, that team is invited as a “team” owner, withrestricted right to the crate. While they have permission to publish or yankversions of the crate, they do not have the ability to add or remove owners.In addition to being more convenient for managing groups of owners, teams arejust a bit more secure against owners becoming malicious.

The syntax for teams is currently github:org:team (see examples above).In order to invite a team as an owner one must be a member of that team. Nosuch restriction applies to removing a team as an owner.

GitHub permissions

Team membership is not something GitHub provides simple public access to, and itis likely for you to encounter the following message when working with them:

It looks like you don’t have permission to query a necessary property fromGitHub to complete this request. You may need to re-authenticate on crates.ioto grant permission to read GitHub org memberships. Just go tohttps://crates.io/login.

This is basically a catch-all for “you tried to query a team, and one of thefive levels of membership access control denied this”. That is not anexaggeration. GitHub’s support for team access control is Enterprise Grade.

The most likely cause of this is simply that you last logged in before thisfeature was added. We originally requested no permissions from GitHub whenauthenticating users, because we didn’t actually ever use the user’s token foranything other than logging them in. However to query team membership on yourbehalf, we now require the read:org scope.

You are free to deny us this scope, and everything that worked before teamswere introduced will keep working. However you will never be able to add a teamas an owner, or publish a crate as a team owner. If you ever attempt to do this,you will get the error above. You may also see this error if you ever try topublish a crate that you don’t own at all, but otherwise happens to have a team.

If you ever change your mind, or just aren’t sure if crates.io has sufficientpermission, you can always go to https://crates.io/login, which will prompt youfor permission if crates.io doesn’t have all the scopes it would like to.

An additional barrier to querying GitHub is that the organization may beactively denying third party access. To check this, you can go to:

  1. https://github.com/organizations/:org/settings/oauth_application_policy

where :org is the name of the organization (e.g., rust-lang). You may seesomething like:

Organization Access Control

Where you may choose to explicitly remove crates.io from your organization’sblacklist, or simply press the “Remove Restrictions” button to allow all thirdparty applications to access this data.

Alternatively, when crates.io requested the read:org scope, you could haveexplicitly whitelisted crates.io querying the org in question by pressingthe “Grant Access” button next to its name:

Authentication Access Control