# Purpose of the `src` Directory in Brush: Rust Workspace Structure Explained

> Discover the purpose of the src directory in Brush. Learn how Rust workspace structure organizes implementation code and entry points following Cargo conventions.

- Repository: [Arthur Brussee/brush](https://github.com/ArthurBrussee/brush)
- Tags: internals
- Published: 2026-05-14

---

**The `src` directories in Brush contain the root modules and implementation code for each crate in the workspace, following standard Cargo conventions to organize entry points, sub-modules, and compilation units.**

The Brush repository (ArthurBrussee/brush) implements 3D Gaussian splatting as a Rust mono-repo workspace. Understanding the purpose of the `src` directory in Brush reveals how the project organizes its multi-crate architecture into independent, compilable units that handle everything from dataset loading to training and rendering.

## Standard Rust Module Organization

Each `src` folder serves as the root of a crate's module hierarchy, containing the entry point files that the Rust compiler uses to begin compilation.

### Root Module Entry Points

Every crate in Brush contains either [`lib.rs`](https://github.com/ArthurBrussee/brush/blob/main/lib.rs) (for library crates) or [`main.rs`](https://github.com/ArthurBrussee/brush/blob/main/main.rs) (for binary crates) directly inside its `src` directory. These files act as the crate root, declaring public APIs and module hierarchies. For example, [`crates/brush-dataset/src/lib.rs`](https://github.com/ArthurBrussee/brush/blob/main/crates/brush-dataset/src/lib.rs) re-exports the public interface:

```rust
pub mod config;
pub mod scene;
pub mod scene_loader;

mod formats;
pub use formats::{DatasetLoadResult, load_dataset};

```

This structure allows other crates to access functionality through clean import paths while keeping implementation details organized in sub-modules.

### Sub-Module Discovery

The compiler follows `mod` statements from the root file to discover additional source files. In `crates/brush-dataset/src/`, the module tree extends into specialized files like [`scene.rs`](https://github.com/ArthurBrussee/brush/blob/main/scene.rs) and [`scene_loader.rs`](https://github.com/ArthurBrussee/brush/blob/main/scene_loader.rs), plus subdirectories such as `formats/` containing [`mod.rs`](https://github.com/ArthurBrussee/brush/blob/main/mod.rs), [`nerfstudio.rs`](https://github.com/ArthurBrussee/brush/blob/main/nerfstudio.rs), and [`colmap.rs`](https://github.com/ArthurBrussee/brush/blob/main/colmap.rs). This organization isolates format-specific parsing logic while maintaining a unified public API.

## Workspace Structure and Compilation

Brush employs a workspace configuration that treats each `src` directory as an independent compilation unit while maintaining cross-crate dependencies.

### Mono-Repo Layout

The top-level [`Cargo.toml`](https://github.com/ArthurBrussee/brush/blob/main/Cargo.toml) defines a workspace whose `members` array points to crate directories under `crates/`. Each member directory contains its own [`Cargo.toml`](https://github.com/ArthurBrussee/brush/blob/main/Cargo.toml) and `src/` folder, creating clear boundaries between concerns like data loading, training logic, and rendering backends.

### Separate Compilation Units

Because each crate maintains its own `src` directory, Cargo can build them independently, cache artifacts, and emit separate library files (`.rlllib` or `.so`). This separation means changes to [`crates/brush-train/src/train.rs`](https://github.com/ArthurBrussee/brush/blob/main/crates/brush-train/src/train.rs) do not force recompilation of [`crates/brush-dataset/src/lib.rs`](https://github.com/ArthurBrussee/brush/blob/main/crates/brush-dataset/src/lib.rs), significantly accelerating development cycles in this multi-crate project.

## Key Crates and Their `src` Contents

The Brush workspace organizes functionality across several specialized crates, each with distinct responsibilities reflected in their `src` structure.

### brush-dataset

Located at `crates/brush-dataset/src/`, this crate handles 3D scene data ingestion. The [`lib.rs`](https://github.com/ArthurBrussee/brush/blob/main/lib.rs) file defines the `Dataset` struct and re-exports loading functions, while [`src/formats/mod.rs`](https://github.com/ArthurBrussee/brush/blob/main/src/formats/mod.rs) delegates to format-specific implementations like [`nerfstudio.rs`](https://github.com/ArthurBrussee/brush/blob/main/nerfstudio.rs) and [`colmap.rs`](https://github.com/ArthurBrussee/brush/blob/main/colmap.rs).

### brush-train

The training logic resides in `crates/brush-train/src/`, containing [`train.rs`](https://github.com/ArthurBrussee/brush/blob/main/train.rs) (implementing the `train` function) and [`config.rs`](https://github.com/ArthurBrussee/brush/blob/main/config.rs) (defining the `Config` struct). These files implement the optimization loop for Gaussian splatting parameters.

### Additional Crates

- **brush-render-bwd**: Implementation in [`crates/brush-render-bwd/src/render_bwd.rs`](https://github.com/ArthurBrussee/brush/blob/main/crates/brush-render-bwd/src/render_bwd.rs) handles backward-pass rendering computations
- **brush-vfs**: Virtual file system abstractions in [`crates/brush-vfs/src/data_source.rs`](https://github.com/ArthurBrussee/brush/blob/main/crates/brush-vfs/src/data_source.rs)
- **brush-process**: Inter-process communication defined in [`crates/brush-process/src/message.rs`](https://github.com/ArthurBrussee/brush/blob/main/crates/brush-process/src/message.rs)

## Practical Implementation Examples

The `src` directories contain the actual implementations consumed by Brush applications. Here are examples demonstrating how code in these directories is used.

### Loading a Dataset

This example uses the `brush-dataset` crate to load training data. The `load_dataset` function is defined in [`crates/brush-dataset/src/formats/mod.rs`](https://github.com/ArthurBrussee/brush/blob/main/crates/brush-dataset/src/formats/mod.rs):

```rust
use brush_dataset::load_dataset;
use brush_dataset::Dataset;

fn main() -> anyhow::Result<()> {
    // Load a NeRFStudio dataset from a folder
    let dataset: Dataset = load_dataset("my/nerfstudio_scene")?;
    println!("Loaded {} training views", dataset.train.views.len());

    // Estimate an up-direction from the camera poses
    let up = dataset.estimate_up();
    println!("Estimated up vector: {up:?}");
    Ok(())
}

```

### Training a Model

The training entry point resides in [`crates/brush-train/src/train.rs`](https://github.com/ArthurBrussee/brush/blob/main/crates/brush-train/src/train.rs), while configuration parsing uses [`crates/brush-train/src/config.rs`](https://github.com/ArthurBrussee/brush/blob/main/crates/brush-train/src/config.rs):

```rust
use brush_train::{train, Config};

fn main() -> anyhow::Result<()> {
    // Parse a TOML config file
    let cfg: Config = toml::from_str(&std::fs::read_to_string("train.toml")?)?;

    // Run the training loop
    train(cfg)?;
    Ok(())
}

```

## Summary

- The `src` directory in each Brush crate follows Cargo's standard layout, containing [`lib.rs`](https://github.com/ArthurBrussee/brush/blob/main/lib.rs) or [`main.rs`](https://github.com/ArthurBrussee/brush/blob/main/main.rs) as the compilation entry point.
- Sub-modules are organized under `src/` using files and folders that mirror Rust's module hierarchy, as seen in `crates/brush-dataset/src/formats/`.
- Workspace configuration enables independent compilation of each `src` tree, caching artifacts for faster builds.
- Implementation files like [`train.rs`](https://github.com/ArthurBrussee/brush/blob/main/train.rs), [`scene.rs`](https://github.com/ArthurBrussee/brush/blob/main/scene.rs), and [`render_bwd.rs`](https://github.com/ArthurBrussee/brush/blob/main/render_bwd.rs) contain the actual logic exposed through public APIs defined in their respective [`lib.rs`](https://github.com/ArthurBrussee/brush/blob/main/lib.rs) files.

## Frequently Asked Questions

### Why does each crate in Brush have its own `src` directory?

Each crate maintains an independent `src` directory because Brush is organized as a Cargo workspace. This separation allows each crate to compile as a distinct unit with its own dependencies and artifact output. According to the Brush source code, the workspace root [`Cargo.toml`](https://github.com/ArthurBrussee/brush/blob/main/Cargo.toml) references these crates under `crates/`, and each follows the standard Rust convention where `src/` contains the implementation code.

### What is the difference between [`lib.rs`](https://github.com/ArthurBrussee/brush/blob/main/lib.rs) and [`main.rs`](https://github.com/ArthurBrussee/brush/blob/main/main.rs) in Brush's `src` folders?

Library crates like `brush-dataset` and `brush-train` use [`src/lib.rs`](https://github.com/ArthurBrussee/brush/blob/main/src/lib.rs) to expose public APIs that other crates can import, while binary crates use [`src/main.rs`](https://github.com/ArthurBrussee/brush/blob/main/src/main.rs) to define executable entry points. In Brush, most crates are libraries ([`lib.rs`](https://github.com/ArthurBrussee/brush/blob/main/lib.rs)) that export functionality such as `load_dataset` or `train`, allowing the application logic to compose these capabilities while keeping the source organized in `src/` directories.

### How does the `src` directory structure affect compilation speed in Brush?

The `src` directories enable faster incremental compilation because Cargo treats each crate as a separate compilation unit. When you modify [`crates/brush-train/src/config.rs`](https://github.com/ArthurBrussee/brush/blob/main/crates/brush-train/src/config.rs), only that crate and its dependents rebuild, while `crates/brush-dataset/src/` and other crates remain cached. This architectural boundary prevents unnecessary recompilation across the mono-repo workspace.

### Where are tests located in relation to the `src` directory in Brush?

Unit tests typically reside within the `src` tree using `#[cfg(test)]` modules inside source files like [`crates/brush-dataset/src/lib.rs`](https://github.com/ArthurBrussee/brush/blob/main/crates/brush-dataset/src/lib.rs), or in separate test files imported via `mod` statements. Integration tests live in a top-level `tests/` folder adjacent to `src/`, while the source code under `src/` may contain doc tests and example functions compiled only when running `cargo test` or `cargo run --example`.