Why does Cargo use the word "bin"?

Cargo uses the word "bin" to mean "program". Though, "bin" is shorthand for "binary", that means "non-textual".
The concept of "textual" is orthogonal with the concept of "program". There are textual programs, binary programs, textual libraries, and binary libraries.
I find quite contradictory the folder "src/bin", as "src" is for textual code. So it means "non-textual textual code".
Wouldn't be better to use "prg" or "exe" to mean "program" (or "executable")?


It's common terminology to call the program file as executable binary, or just binary for short.

If you're familiar on unix-like OS, like linux, executable files are tend to be stored under /bin, /usr/local/bin etc.


Yes. Which is why Rust's use of 'bin' as in 'src/bin' seems totally misleading and daft.

I was wondering about this just yesterday when I found one could build multiple executables from a single crate by putting source files that each contained 'main()' into 'src/bin'.

So now we have non-binary, non-execuatble files in a directory call 'bin'. WTF?

Meanwhile our actual executable binaries are somewhere under 'target'.

1 Like

Under Windows, it's common terminology to end program names with ".exe", static library names with ".lib", dynamic library names with ".dll".
The fact that Unix creators wrongly named "bin" a folder containing also scripts (or wrongly put scripts in a folder named "bin"), and avoided to put binary libraries into it, is not a good reason to persist in such error.

In the context of Cargo I think it's more accurate to think of it as shorthand for "binary crate".

A package can have multiple binary crates by placing files in the src/bin directory: each file will be a separate binary crate.

So you could say the full names are "src/binary crates" and "src/library crate", though you could consider that inappropriate as well.


I think it's most appropriate to see "bin" as shorthand for "binary", but also to see "binary" as a synonym for "program" and/or "executable" regardless of its implementation details e.g. whether it is a compiled program or a shell script (which don't matter from the perspective of the caller anyway).

That is how I've always viewed it and I've never had any cognitive dissonance about this as a result of it.


But exactly there is the cognitive dissonance for me. The suff under src/bin is readable source code text. It is not any kind of binary data, binary executable or interpreted language executable script.

This extends the meaning of "bin" to cover non-runnable source code files as well.

The only way I can rationalize it is to think that src/bin is where I put the sources for the binaries I want created from this crate. Almost cognitive harmony :slight_smile:

It is the source for the binaries. Seems pretty clear to me.


Yes, yes, like I said "Almost cognitive harmony" when you look at it that way.

Like many things in Rust cognitive harmony is only achieved after you have discarded all notion of what things mean that you have picked up over decades elsewhere.

No, instead it's an executable file which incidentally is human-readable. The latter part of that sentence doesn't matter even a little bit, as it's an implementation detail.

It extends it to "runnable, human readable programs". As in, they're still by definition executable.

1 Like

I cannot agree with that idea.

The stuff under src/bin is in no way executable by any operating system I know of. It's Rust source code text. Just text.

But yes, if we go with that idea then "bin" is anything at all. Which is ultimately true, everything is just binary, zeros and ones, on our computers at the end of the day after all.

Indeed that's a little different.

IMO anything with $PROJECT/src/ as an ancestor directory is source code, regardless of the name of the directory under it, no ifs or buts about it.
That goes for src/bin/ too.

The fact that it's called bin is to me a hint that it's the source code we're defining of the executable that will be run when using cargo run or the like.

1 Like

My first reaction is like @jjpe's: a "Rust binary" has a clear meaning of being a runnable / an application.

But after reading this thread, I've tried to "take a step back", and do agree that path src/bin is a bit of an oxymoron.

  • I guess that in practice, src/bin does not come up that often (rather, the simpler src/main.rs, which makes sense given how pervasive main() is w.r.t. the entry point of an application), so by the time src/bin/smth.rs does come up, the "Rust binary" vs. "Rust library" dichotomy has had enough time to sink for it not to be a shocker.

But, to be honest, if we could go back and change things, that folder could perfectly have been named src/run (due to cargo run) or src/apps (for some hypothetical cargo build --app when having to disambiguate vs. lib), or even src/exe, although I am personally not that fond of the latter, since exe for an application is more Windows-esque: similarly to binary, a library can be seen as an executable since it does carry executable code within it (in a way, there is little difference between being executable or being callable).

Now, in practice, for those who don't feel comfortable with src/bin, know that such path is just a default, and you are free to override it!

name = "whatever"
path = "src/apps/whatever.rs"
# or
path = "src/run/whatever.rs"

if so doing becomes pervasive enough, (only) then could cargo add compatibility flags, such as --app, as a --bin synonim, and maybe even [[app]] as a [[bin]] synonim Cargo.toml-wise. Who knows?


I would like "exe". It's a Windows-ism, certainly, but the way Cargo uses "bin" is a POSIX-ism.

That's all it is. Rust clearly used "bin" as an analogy to FHS. It makes sense as an analogy (a "bin crate" is the kind of thing that belongs in /bin), but not as standalone terminology (Rust crates always produce binaries when compiled). If would make just as much sense to call it an "exe", as an analogy, but the name would also be logical in isolation ("executable" are executed, while "libraries" are consulted for parts).

I don't like "app" because it's usually used to refer to a complete product, while an "exe" might be a small part of a larger system (postfix-smtpd is not an app, but rather a tiny part of Postfix).


At the end of the day it's not a big deal.

It is what it is. It may or may not be different to what you are used to thinking. Every system has it's own terminology. Language changes over time no matter what us old guys think about it.

Anyone remember when "firmware" was called that because it was firmly, unchangeably, built into your hardware?



I'm not so sure about that.

Typically executable programs on Windows have a ".exe" extension to their file name.

Typically executables on Unix like systems do not have a ".bin" extension. Or any extension.

This is all so complicated now a days. Back in the day it was source code as into a compiler, binary code out.

Now we input source code from under a bin directory.

Ah well.

They don't, but regardless of what file it is - .py, .sh, or no extension, all binaries belong in either /bin or /usr/bin in Unix systems. Given that executables don't have a specific extension, like Windows, I think it's an apt analogy?

Like, on Windows, all executables have an exe extensions, and that's what tells you it's an executable. On linux, all executables are placed into <somewhere>/bin, and that's what tells you it's an executable.

Sure, linux doesn't use an extension, but does that really invalidate the analogy?

No, it does not. We should not worry about it so much.

I have seen executable binary programs in /etc on Debian.

I have seen my friend change a ".dll" extension to ".exe" and run it on Windows.

It's a mess, and whatever Rust does is just another twist in the spaghetti. We can handle it.

But, please, please, can we never refer to anything in the Rust world as an "app"?



1 Like