# Brush Project Structure: Workspace Layout, Applications, and Core Crates

> Explore the Brush project structure, a Rust workspace featuring four cross-platform apps and sixteen crates for 3D Gaussian splatting. Learn about its layout and core components.

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

---

**The Brush project is organized as a Rust workspace containing four cross-platform applications and sixteen specialized crates that collectively implement a 3D Gaussian splatting pipeline with support for desktop, mobile, web, and CLI targets.**

The Brush repository follows a modular architecture defined in the top-level [`Cargo.toml`](https://github.com/ArthurBrussee/brush/blob/main/Cargo.toml), which declares a workspace grouping independent yet interoperable components. This structure separates rendering algorithms, training logic, and platform-specific user interfaces, enabling the codebase to target native GPU backends (CUDA/Metal) and WebAssembly simultaneously according to the ArthurBrussee/brush source code.

## Workspace Structure and Configuration

The foundation of the Brush project structure resides in the root [`Cargo.toml`](https://github.com/ArthurBrussee/brush/blob/main/Cargo.toml), which defines the workspace members array spanning lines 4-18. As implemented in `ArthurBrussee/brush`, this declaration lists every crate and app as a first-class component, allowing independent compilation or unified builds while sharing dependency patches across the entire project.

### Dependency Patches

Because Brush targets WebGPU for cross-platform rendering, the workspace patches the `wgpu` and `cubecl` crates to include custom WebGPU interop and subgroup primitives. These patches, located at lines 18-34 of the top-level [`Cargo.toml`](https://github.com/ArthurBrussee/brush/blob/main/Cargo.toml), ensure identical shader code executes on native drivers and browser-based WebAssembly environments.

## Applications (`apps/`)

The `apps/` directory contains four distinct entry points that expose Brush functionality to different platforms and use cases.

### Desktop and Mobile UI (`brush-app`)

The **`brush-app`** crate delivers a full-featured graphical interface built with `eframe` and `egui`, targeting desktop and Android devices. The application entry point at [`apps/brush-app/src/main.rs`](https://github.com/ArthurBrussee/brush/blob/main/apps/brush-app/src/main.rs) initializes the GUI event loop, while Android-specific Gradle build files in the same directory handle mobile deployment.

### Command-Line Interface (`brush-cli`)

For automated training and batch processing, **`brush-cli`** exposes subcommands including `train`, `render`, and debug utilities. The command definitions reside in [`apps/brush-cli/src/lib.rs`](https://github.com/ArthurBrussee/brush/blob/main/apps/brush-cli/src/lib.rs), which parses arguments and delegates to the underlying `brush-process` and `brush-train` crates. Users invoke the CLI via the `brush` binary installed from this crate.

### WebAssembly Demo (`brush-js`)

The **`brush-js`** application compiles the rendering pipeline to WebAssembly using `wasm-pack`, enabling browser-based Gaussian splatting visualization. The TypeScript entry point at [`apps/brush-js/web/src/main.ts`](https://github.com/ArthurBrussee/brush/blob/main/apps/brush-js/web/src/main.ts) initializes the WASM module and connects it to a Vite-based frontend, configured via [`apps/brush-js/web/vite.config.ts`](https://github.com/ArthurBrussee/brush/blob/main/apps/brush-js/web/vite.config.ts).

### C Bindings (`brush-c`)

Though not currently listed in the workspace members array, **`brush-c`** provides minimal C bindings for integrating Brush into existing C/C++ codebases. The FFI interface is implemented in [`apps/brush-c/src/lib.rs`](https://github.com/ArthurBrussee/brush/blob/main/apps/brush-c/src/lib.rs), exposing core splatting functions to foreign code.

## Core Library Crates

The `crates/` directory houses sixteen specialized libraries that implement the mathematical and rendering operations, organized by functional responsibility.

### Rendering Pipeline

**`brush-render`** implements the forward-rendering pipeline—culing, depth-sorting, and rasterizing 3D Gaussians. In [`crates/brush-render/src/lib.rs`](https://github.com/ArthurBrussee/brush/blob/main/crates/brush-render/src/lib.rs) (lines 12-35), the crate exposes the **`render_splats`** function and **`SplatOps`** trait, which abstract GPU kernel execution across different backends. The companion crate **`brush-render-bwd`** mirrors this structure but implements gradient-aware rasterization for differentiable rendering during training.

### Data Management

**`brush-dataset`** handles loaders for COLMAP and Nerfstudio data formats, parsing camera parameters and images in [`src/scene_loader.rs`](https://github.com/ArthurBrussee/brush/blob/main/src/scene_loader.rs). This crate relies on **`brush-vfs`**, which provides a virtual-file-system abstraction allowing data streams from local disk, HTTP, or in-memory buffers through a unified interface defined in [`crates/brush-vfs/src/lib.rs`](https://github.com/ArthurBrussee/brush/blob/main/crates/brush-vfs/src/lib.rs).

### Training Infrastructure

**`brush-process`** orchestrates the training loop through message-passing channels and configuration structs defined in [`src/lib.rs`](https://github.com/ArthurBrussee/brush/blob/main/src/lib.rs). This crate wires together datasets, models, and optimizers while managing state transitions. The **`brush-train`** crate builds upon this to implement high-level training logic, checkpoint scheduling, and optimizer step management.

### Platform Abstractions

**`brush-async`** contains platform-agnostic async runtime helpers that bridge native Tokio runtimes and WASM single-threaded execution, located in [`crates/brush-async/src/lib.rs`](https://github.com/ArthurBrussee/brush/blob/main/crates/brush-async/src/lib.rs). **`brush-cube`** provides utilities for the `cubecl` backend required by the Burn machine learning framework.

### Supporting Utilities

Additional specialized crates include **`brush-sort`** (spatial sorting algorithms), **`brush-prefix-sum`** (parallel scan operations), **`brush-loss`** (photometric loss functions), **`brush-serde`** (serialization formats), **`lpips`** and **`lpips-convert`** (perceptual image metrics), **`colmap-reader`** (COLMAP format parsing), **`rrfd`** (RAW file handling), and **`brush-bench-test`** (GPU kernel benchmarking and fuzz testing).

## Implementation Examples

The modular Brush project structure enables flexible integration across different contexts.

### Rendering from Rust

To render a scene using the core library:

```rust
use brush_render::{render_splats, SplatRenderMode, MainBackend};
use brush_vfs::Vfs;
use brush_dataset::Scene;

fn main() {
    // Load a scene (COLMAP or Nerfstudio format)
    let scene = Scene::load("my_dataset/scene.json").unwrap();

    // Build the renderer
    let renderer = MainBackend::default();

    // Render with default camera and mode
    let output = render_splats(
        &renderer,
        &scene,
        SplatRenderMode::Color,
        /* background */ [0.0, 0.0, 0.0].into(),
    )
    .await
    .unwrap();

    // Save the image
    output.write_to_path("render.png").unwrap();
}

```

*Source references*: [`crates/brush-render/src/lib.rs`](https://github.com/ArthurBrussee/brush/blob/main/crates/brush-render/src/lib.rs) exposes `render_splats`, while [`crates/brush-dataset/src/scene.rs`](https://github.com/ArthurBrussee/brush/blob/main/crates/brush-dataset/src/scene.rs) handles scene loading.

### Training via CLI

The command-line interface supports headless training with viewer support:

```bash
brush train \
   --data ./my_dataset \
   --output ./results \
   --epochs 200 \
   --with-viewer

```

### Web Deployment

To run the WebAssembly demonstration locally:

```bash
cd apps/brush-js
npm install
npm run dev   # Starts Vite with the WASM bundle

```

This executes the entry point at [`apps/brush-js/web/src/main.ts`](https://github.com/ArthurBrussee/brush/blob/main/apps/brush-js/web/src/main.ts), which loads the compiled module.

## Summary

- The **Brush project structure** is defined by a Cargo workspace in the root [`Cargo.toml`](https://github.com/ArthurBrussee/brush/blob/main/Cargo.toml) spanning lines 4-18, grouping four applications and sixteen crates.
- **Applications** in `apps/` provide platform-specific entry points: desktop/mobile GUI (`brush-app`), CLI tools (`brush-cli`), web demos (`brush-js`), and C bindings (`brush-c`).
- **Core crates** separate concerns into rendering (`brush-render`, `brush-render-bwd`), data loading (`brush-dataset`, `brush-vfs`), and training orchestration (`brush-process`, `brush-train`).
- **Dependency patches** for `wgpu` and `cubecl` at lines 18-34 of the workspace root enable simultaneous compilation for native CUDA/Metal and WebAssembly targets.
- Key source files include [`crates/brush-render/src/lib.rs`](https://github.com/ArthurBrussee/brush/blob/main/crates/brush-render/src/lib.rs) (forward rendering API), [`crates/brush-process/src/lib.rs`](https://github.com/ArthurBrussee/brush/blob/main/crates/brush-process/src/lib.rs) (training loop), and [`apps/brush-cli/src/lib.rs`](https://github.com/ArthurBrussee/brush/blob/main/apps/brush-cli/src/lib.rs) (command definitions).

## Frequently Asked Questions

### What is the difference between brush-render and brush-render-bwd?

**`brush-render`** implements the forward-only rasterization pipeline for image synthesis, exposing `render_splats` and `SplatOps` traits in [`crates/brush-render/src/lib.rs`](https://github.com/ArthurBrussee/brush/blob/main/crates/brush-render/src/lib.rs). **`brush-render-bwd`** mirrors this structure but implements gradient-aware rasterization required for training, computing derivatives with respect to Gaussian parameters during the backward pass.

### How does the Brush project support both native and web platforms?

The **`brush-async`** crate abstracts runtime differences between native Tokio and single-threaded WASM environments. Additionally, the root [`Cargo.toml`](https://github.com/ArthurBrussee/brush/blob/main/Cargo.toml) patches `wgpu` and `cubecl` (lines 18-34) to include WebGPU interop, allowing identical GPU kernels to compile for CUDA/Metal and WebAssembly targets.

### Which crate handles loading COLMAP datasets?

**`brush-dataset`** manages data ingestion for COLMAP and Nerfstudio formats, specifically through [`src/scene_loader.rs`](https://github.com/ArthurBrussee/brush/blob/main/src/scene_loader.rs) which parses camera intrinsics, extrinsics, and image files. This crate depends on **`brush-vfs`** to abstract file system operations, enabling the same loading code to work with local datasets, remote HTTP streams, or in-memory buffers.

### Where is the training loop implemented?

The training loop resides in **`brush-process`**, which orchestrates message-passing between dataset loaders, the renderer, and optimizers in [`crates/brush-process/src/lib.rs`](https://github.com/ArthurBrussee/brush/blob/main/crates/brush-process/src/lib.rs). While `brush-process` handles the communication infrastructure, **`brush-train`** provides the high-level logic for building models, scheduling optimization steps, and recording checkpoints.