Hello humans and computational agents,
Below the --- divider below you will find a section that I agree with but Claude Opus 4.7 drafted. I don't just use LLMs to tell me what I want to hear, and I don't casually dump their outputs into the public sphere. I gave the early drafts LOTS of pushback and guidance.
Why? I'm beyond tired of sloppy thinking. I'm tired of post-hoc rationalization. So much that I'm pretty much done with Hacker News and Lobsters. These are places where good reasoning goes to die, but too few admit it.
Enjoy! ... but first, I wrote my own prefatory rant for your consideration.
Great software is one of the rare places where get to really do things well. So let's make the most of it.
Many of us, much of the time, just talk. Words come out of our mouths. Characters go onto screens and into files. Meanwhile, are we thinking about their truth?
People "just saying shit on autopilot" really pisses me off, because it leads to all sorts of downstream stupidity, pain, and (in some cases) unnecessary death.
There is a connection here to Trumpism. How many people will say "yeah, they voted for Trump but they're otherwise good people". Yes, many people who voted for Trump are are friendly and net-positive in their local communities. Two things can be true at the same time... And their collective choices have really screwed us -- and themselves. Look at what Trump is doing with healthcare, with an unnecessary war in Iran, with his corruption.
If this doesn't "bother" you, fine. Maybe you've gotten used to it for your own sanity. That's fine too. But at least understand there are people around who are trying to fucking hold the line about good reasoning. Call us pedants. Call us overly particular. Some of us might be neurodivergent. But when people are sincerely using the best reasoning they can in service of humanitarian and social goals, it is pretty hard to fault that.
So, yeah, I'm ranting. I'm advocating for precision, speaking the truth, even in areas where some people might say "oh that doesn't matter".
-
Step one is recognizing one is probably rationalizing.
-
Step two is recognizing when one is possibly wrong... or just right because of luck.
-
Step three is recognize you probably WANT to say "meh, I don't care to fix that". Admit a part of you wants to be a lazy, defensive asshole.
-
Step four is getting over #3 and saying "Oops" and fucking fixing it.
-
Step five is building an identity that says "Yep, I was wrong, and I'm getting better."
Rant concluded.
P.S. If nothing else, think on this: if you can't admit you're wrong and fix your thinking on the trivial, pedantic things, how can you criticize people that can't change their mind because of deep-seated cultural reasons?
packages/ is the correct name for the directory holding workspace members.
crates/ was cargo culted and it is wrong.
- Package — a bundle of one or more crates, described by a single
Cargo.toml. - Crate — the unit of compilation; one invocation of
rustc. Produces either a library or an executable. - Crate root — the single source file
rustcstarts from:src/lib.rsfor a library crate,src/main.rsfor the default binary crate. - Module — a named scope within a crate, declared with
mod. Modules are purely a source-level organizational tool. They do not affect compilation boundaries. - Workspace — a set of packages sharing a common
Cargo.lockandtarget/directory, declared by a rootCargo.tomlwith a[workspace]section.
The hierarchy: workspace > package > crate > module.
Each subdirectory under crates/ contains a Cargo.toml, making each one a package by definition. In the common case — one src/lib.rs, no extra binaries — the package also contains exactly one crate, so the misnomer goes unnoticed.
That's the trap. "It works most of the time" is not the same as "it is correct." If your term is only accurate under certain conditions, you didn't pick the right term — you got lucky. And luck runs out.
There's also a human factor. Most people don't go back and fix a name once it's in place. It feels like an admission, it takes effort, and nothing is visibly broken. So the wrong word stays. The better move is to notice the slip early and say "oops" — then fix it before it fossilizes. Pick the word that is correct for the general case, not the word that happens to survive the common case.
The directory holds things that rustc compiles. Each subdirectory maps to a compiled artifact. Naming it after the compilation unit reflects what Cargo ultimately does with each member. In the common case it isn't wrong, and "crate" is Rust's most recognizable brand-level word.
A package can contain multiple crates: one library crate (src/lib.rs) plus any number of binary crates (src/bin/*.rs). A directory called crates/server that contains src/lib.rs, src/bin/serve.rs, and src/bin/migrate.rs holds three crates — not one. The name implies a 1:1 mapping that Cargo's own spec does not guarantee.
packages/ has no equivalent failure mode. Each subdirectory contains exactly one Cargo.toml, which is the definition of a package. The name is always correct.
Conventions shift. The Rust community has shown it can revisit terminology when precision matters. This one is worth a nudge.
These definitions get skimmed. The words feel interchangeable until they aren't.
- A package can have multiple binary crates. If you don't know that, you add a new package when you needed a new
[[bin]]target — unnecessaryCargo.toml, unnecessary compilation unit. - Crates have hard API boundaries. Modules do not. Mistaking one for the other leads you to
pub usethings you didn't mean to expose, or to split a crate when a module would do. rustcrebuilds at the crate level, not the module level. If you think modules are the boundary, incremental build behavior will surprise you.- Workspace-level dependency deduplication works at the package level. Misunderstanding the terms makes
[workspace.dependencies]harder to reason about. - Error messages from
rustcand Cargo use these terms precisely. If your mental model is fuzzy, the messages read as noise. - Cargo features are per-package, not per-crate. A package with multiple crates shares one feature set. That surprises people who think the crate is the top-level unit.
extern crate(rare but still appears in older code and macros) refers to a crate, not a package. Searching for the wrong thing wastes time.- Proc macros must live in their own package — not just their own crate, their own package. This is a common stumbling block when first writing derive macros.
- The
[lib]and[[bin]]sections inCargo.tomlconfigure crates. TheCargo.tomlitself describes the package. Editing the wrong mental layer leads to wrong edits. - Visibility (
pub,pub(crate),pub(super)) is scoped to modules and crates, not packages.pub(crate)does not mean "visible within this package's other crates."