[Pre-RFC] Domains as namespaces


There isn’t any. This is intentional, because doing this would be a terrible idea.

Allowing people to refer to namespaces from within the source code would make it impossible to switch out unmaintained crates with maintained ones (who have been forked and live under a different organization) without having to touch every single source file.

That’s an atypical understanding of namespaces. Not that it is necessarily bad. I think the ability to swap out unmaintained packages for maintained packages has a certain appeal, but what you are proposing does run counter to what people will be used to. In particular it is not what the other main domain-based namespacing system does (the JVM ecosystem). It is also not how npm scopes work.

Including namespaces in how you refer to packages in code is the standard way to do things. Calling it a terrible idea out of hand is unjustifiably dismissive. The position that conflicts won’t happen much and when they do you can just use crate renaming is an interesting one. It has the benefit of keeping the language the same. I really like the idea of keeping the changes confined to the package manager.


If you go federated, you can sign packages and cargo can verify the signatures. The server signature would be stored somewhere like .well-known, and cached locally both in crates.io and in Cargo.lock (or maybe a Cargo.sig – we don’t wanna leave out library packages!). This means if a domain changes ownership, this won’t lead to a potential security issue.

Ofc, it provides little to no protection against that domain/server being hacked, and servers are generally easier to hack than a crate developer’s computer. This is one point where a centralized registry is beneficial - if you have many registries, it’s likely that at least some of them will have security vulnerabilities. If you have a centralized registry, it’s a lot easier to patch those vulns.

In any case, federation wouldn’t necessarily make the attack surface any smaller - crates.io would still be a single point of failure, as it’d be the default registry. If the ability to use alternative registries takes off, tho, it could lead to a smaller attack surface, as different registries could be using different software with different vulnerabilities or even a strong layer of hardening. Some registries could even be served over static pages + a cron job that checks for updates, making hacking them quite a task!


Maybe this is a tangent, but this term “federated” has shown up enough times that I want to stop and ask what that word means.

The only definition I was able to find via googling was Julia’s:

which sounds like exactly what we’re going to get from cargo supporting alternative registries, so whatever @Soni means by “federated” must be more than just that. Right?


it means the ability to publish crates depending on example.org’s whatever on crates.io, and having crates.io fetch the crates from example.org and cache them in crates.io, and having cargo fetch example.org’s packages from crates.io, so it’s NOT what the “alternative registries” RFC proposes.

the “alternative registries” RFC proposes: registries are independent and fully isolated, so they can’t ever talk to eachother. dependencies from different registries aren’t allowed to be mixed together.

it’s completely different. both involve independent parties and independent moderation, but, for benefits of federation: (non-federation lacks these, so they can be considered drawbacks for non-federation)

  • reliability, as if a registry goes down you can just switch to another and everything’s cached
  • deduplication, rather than publishing (separately) on multiple registries, you only publish once and it gets automatically distributed
  • namespacing (as talked about in this post)
  • there are more I can’t currently think of, but I encourage ppl to talk about them as well (:

otoh, federation has the following drawbacks compared to non-federation:

  • wider attack surface, as you can hack another registry and the hacked contents will get automatically distributed as with a non-malicious crate. (malware scans help mitigate this problem - remember: always sanitize your inputs, even if they come from a federated server ;))
  • um, there are probably more that I can’t think of? (“change of domain ownership” etc aren’t a problem if the server signature (public key) also changes, so I’m not sure if it should be counted here. but do note that the signature is independent of the domain name!)


Maybe we are talking about different things, because this is in fact exactly what Maven does.

One arbitrary example: jaxb-core was previously published under the following coordinates:


Since a while this package has been migrated to:


For users of this artifact no changes except updating the groupId have been necessary.

This is what I’m proposing. Fortunately, Rust doesn’t even have the rather arbitrary (and unenforced) package naming convention and I’m not suggesting that Rust should adopt it. (That design smells a bit like the stuff suggested in [Pre-RFC]: Packages as Namespaces though, which I think is a poor idea for the obvious reasons.)


I haven’t used the JVM ecosystem extensively, so perhaps I was wrong. I was under the impression that the groupId would show up in import statements in your code as well as any place where you use the fully qualified name in an expression. For example, I see some spring tutorials that contain the line import org.springframework.web.bind.annotation.RequestMapping;. Isn’t org.springframework from the groupId of the package?

Fortunately, Rust doesn’t even have the rather arbitrary (and unenforced) package naming convention and I’m not suggesting that Rust should adopt it. (That design smells a bit like the stuff suggested in [Pre-RFC]: Packages as Namespaces though, which I think is a poor idea for the obvious reasons.)

Could you expand on that a bit? I’m not sure what you mean by “arbitrary (and unenforced) package naming convention”. Is it a java naming thing? Also, if you have objections to packages as namespaces besides the ability to name crates of the same name in different namespaces, I would love it if you would share them over on that thread.


Using reverse url to name packages in Java is just an old convention (since java 1.0 IIRC, long before any package manager), but it is not mandatory at all.


Ah, thanks!


(What Uther said.)

Basically the groupId has no effect on the artifactId has no effect on the package name. This is bad, because you have to rely on conventions and if someone ignores them, you have to guess.

What I propose is organization = "some.domain.org", name = "some_name" and use some_name; to be the one and only way that is allowed in Rust. (~ keep everything that exists as it is, add organization)


Where do existing packages where package.name and lib.name don’t match fit into this?

I think a more interesting end goal is embracing the separation between package.name and lib.name, and effectively having everyone use rename-dependencies (by convention instead of requirement):

serde = { version = "1.0", org = "serde.rs", package = "serde" }

This way it doesn’t matter what lib.name is, just the name of the package (and organization).


That makes sense. It seems like a pretty reasonable way to approach things.


If crate name is still unique through out of crate.io, people still need squatting crate name. Why you claim namespace addresses the squatting issue?


Mhhh, maybe I’m missing something … were is this claimed?


I’m very supportive of this. I come from Go, where it is very normal to have domain names in the source code directly. No, it doesn’t matierially make it harder to switch from one package to another – either they implement the same API (and it’s a search & replace operation) or they don’t (and it’s a bigger task anyway).

It irks me to no end how misleading the crates.io namespace is – I’ve found myself using bad, unmaintained, and suboptimal crates on a regular basis because it looks like a curated namespace but isn’t. At least with domains we make it clear that you’re just picking up some person’s idea of the thing.


I’d rather not wrap cargo builds with an additional layer of Makefiles or other scripts, because that’s exactly what this will turn into.

Take my dirs crate for instance: The original home_dir function in the standard library supported every platform Rust supports.

The replacement only supports Linux, macOS (only tested on CI), Windows (only tested on CI) and Redox (not regularly tested at all).

I’d love if people with obscure platforms were able to just drop in their own implementations for platforms I can’t support/test. This is a no-brainer if the source code is properly decoupled from the organization that provides the implementation.

My proposal does that, so having one Cargo.toml should suffice even if different platforms depend on “different” dirs crates for different platforms.

Your suggestion would make it necessary to rewrite source files during the build and probably adjust the Cargo.toml file as necessary, too. (You could do both with Makefiles for example, or whatever scripting language you fancy.)

I’d rather not go the Cargo.toml + Makefiles way, if a task can be solved with Cargo.toml alone. Popular languages picking a design is a rather good indication to avoid that design in general, if there aren’t any convincing reasons to reconsider (explanation below).


You said, keep everything that exists as it is, add organization.

Crate name is unique now, which you don’t change.


Do you need to verify your domain?

I’m pretty sure that this idea, if adopted, will also add a lot of lines to config.toml file. Maybe for Java world it’s ok to have huge xml configs, but I don’t want this destiny for Rust.


No, because either you’re hosting a package there or you’re not. There’s no arbiter that you have to prove things to.


I think my point was more intended to outline the user-facing changes a developer might see.

Namespaced crates would be unique in one organisation, but different organizations could of course have crates with the same name, often even intentionally.


[Everyone, please try to raise the level of discussion here. Focus on adding new information or ideas, and asking questions about things you need clarified. Flag inappropriate or unconstructive comments rather than replying to them.]