Is Structuring a Rust Project As lib.rs + main.rs Hurting Compilation Time?

Are you compiling twice by having a separate lib.rs and main.rs in Rust?

2025-07-26

TLDR: It does not.

I am currently doing a personal project in Rust, and by habit, I always separate out a single executable logical unit to library + binary crates.

So for example, a editor.exe would actually be comprised of a editor binary crate and an editorlib library crate.

|-- editor
|    |-- main.rs
|
|-- editorlib
|    |-- lib.rs
|    |-- xx.rs

Usually projects will put lib.rs and main.rs together in a single crate (which we will also explore later), but even then, they are compiled as separate units.

Having a separate lib.rs and main.rs in the same crate is considered idiomatic Rust (as it is recommended in the Rust intro book), and there's some advantages (e.g. being able to do integration tests).

But I also wondered whether this might incur additional compilation time, compared to just having everything on a single binary crate (especially if you don't care about reusability).

The idea here is: are we actually compiling the same things twice by having a separate lib.rs and main.rs?

So I decided to try out compiling all 3 different possible ways that you can structure the codebase, and measure the difference in build timings.

Note that the experiment here isn't very scientific, I just ran compilation for each codebase structure twice, and take the best of the two timings. The building environment isn't exactly stable either (like there are other things running in the background that may affect CPU performance). So there can be a difference of 1-2 seconds even when recompiling the same structure.

The builds are done and measured using cargo clean && cargo build --timings. There's no significant code changes, we are only moving the files around.

With that said, let's jump into the experiment.

Org 1 - Have a separate lib + bin crate

We first try out the codebase structure that we have seen at the start of the post:

|-- editor
|    |-- main.rs
|
|-- editorlib
|    |-- lib.rs
|    |-- xx.rs

The total time it took to build both editor and editorlib is ~14.5 seconds. The editorlib itself took 6.5 seconds. So we hope that if we adjust the codebase structure, we can at least reduce 6.5 seconds of built time.

Org 2 - Put them in the same crate, but still use lib.rs and bin.rs

This should not have any difference compared to org 1, but maybe we can unlock some kind of optimization given that the lib portion is not used outside of editor?

|-- editor
     |-- lib.rs
     |-- main.rs
     |-- xx.rs

No dice. Of course, it is still compiled as separate units, so the total duration is still ~14.5 seconds.

Now let's just combine everything.

Org 3 - Absorb library code into the binary, no separate lib

We obliterate lib.rs, so now no one can actually even import the code outside of editor.

|-- editor
     |-- main.rs
     |-- xx.rs

The total duration is ~13 seconds, which is only a reduction of 1.5 seconds.

The reduction of 1.5 seconds is not much given our build environment. If the same code is being compiled twice, we would have expected a reduction of ~6.5 seconds.

Hence, we can conclude that there weren't any re-compilation of the same code, and therefore reorganizing the codebase structure did not help much in terms of reducing the compile time.

And everyone can use their favorite codebase structure as they deem fit.

[[[ All Posts ]]]