How to Contribute to the Brush Project: A Complete Guide for 3D Gaussian Splat Developers

To contribute to the Brush project, fork the repository, install Rust ≥ 1.88 with Android and WASM targets, run cargo test --all to verify your setup, then submit changes following the conventional commit format and the upstream CI workflow.

Brush is a Rust-first, cross-platform 3D reconstruction engine that implements Gaussian splatting using the Burn machine learning framework. Whether you want to optimize GPU kernels, extend the desktop UI, or improve the WebAssembly demo, understanding the crate structure and contribution workflow is essential. This guide walks you through the exact steps needed to modify the codebase at github.com/ArthurBrussee/brush and submit a successful pull request.

Understanding the Brush Architecture

Brush is organized as a Cargo workspace with separate crates handling distinct stages of the 3D reconstruction pipeline. Before contributing, identify which crate aligns with your goal:

The workspace configuration resides in the root Cargo.toml, which defines shared dependencies and Rust version requirements (≥ 1.88) across all crates.

Setting Up Your Development Environment

1. Fork and Clone the Repository

Start by creating a personal fork via the GitHub UI, then clone it locally:

git clone https://github.com/<your-username>/brush.git
cd brush

2. Install the Rust Toolchain

Brush requires Rust ≥ 1.88. Install the latest stable toolchain and add required compilation targets:

rustup update stable
rustup target add aarch64-linux-android   # Required for Android builds

rustup target add wasm32-unknown-unknown  # Required for WASM builds

Install additional platform-specific tools:

cargo install cargo-ndk   # Android cross-compilation helper

cargo install wasm-pack   # WASM packaging utility

cargo install cargo-bloat   # Optional: binary size analysis

cargo install rerun-cli     # Optional: visualization support

The Contribution Workflow

Running the Test Suite

Verify your environment by executing the full test suite locally. Passing tests locally prevents CI failures on your pull request:

cargo test --all

This command mirrors the GitHub Actions workflow defined in .github/workflows/ci.yml.

Making Your Changes

Select the appropriate crate based on your contribution type:

  • New GPU kernels → Modify crates/brush-render or crates/brush-render-bwd.
  • New loss terms → Add code to crates/brush-loss.
  • UI modifications → Edit files under crates/brush-app/src/ui/.
  • Web demo improvements → Work within apps/brush-js.

Before committing, enforce the project’s code style:

cargo fmt
cargo clippy -- -D warnings

Every new public API requires unit or integration tests in the same crate. Reference existing test patterns, such as those in crates/brush-loss/tests/reference.rs.

Building and Verifying Across Platforms

Validate your changes on the target platform:

Platform Build Command
Desktop (Linux/macOS/Windows) cargo run --release
Web (WASM) npm run dev (inside apps/brush-js)
Android cargo ndk -t arm64-v8a -o crates/brush-app/app/src/main/jniLibs/ build --release then ./gradlew installDebug

Ensure the application launches correctly and new functionality behaves as expected on your target platform.

Committing and Submitting Your Changes

Create a feature branch using conventional commit naming:

git checkout -b feature/my-new-kernel
git add .
git commit -m "feat(render): implement fast Gaussian splat kernel"
git push origin feature/my-new-kernel

Open a pull request against the main branch. Fill out the auto-generated PR template completely. The CI pipeline will run cargo test --all across all supported targets. Respond promptly to reviewer feedback, which may involve updating documentation or adjusting code in files like Cargo.toml or kernel implementations.

Code Example: Adding a New Rendering Kernel

The following example demonstrates adding a custom GPU kernel to the brush-render crate, following the pattern established in crates/brush-render/src/kernels/map_gaussians.rs:

// File: crates/brush-render/src/kernels/my_custom_kernel.rs
//! A simple example kernel that multiplies splat colour by a constant factor.

use wgpu::util::DeviceExt;

/// Entry point called by the CPU side.
pub fn run_my_kernel(
    device: &wgpu::Device,
    queue: &wgpu::Queue,
    gaussian_buffer: &wgpu::Buffer,
    output_buffer: &wgpu::Buffer,
    factor: f32,
) {
    // Load the shader (WGSL) from the same directory.
    let shader = device.create_shader_module(&wgpu::ShaderModuleDescriptor {
        label: Some("my_custom_kernel"),
        source: wgpu::ShaderSource::Wgsl(include_str!("my_custom_kernel.wgsl").into()),
    });

    // Create a pipeline layout and compute pipeline.
    let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
        label: Some("my_custom_kernel_layout"),
        bind_group_layouts: &[],
        push_constant_ranges: &[],
    });

    let pipeline = device.create_compute_pipeline(&wgpu::ComputePipelineDescriptor {
        label: Some("my_custom_kernel_pipeline"),
        layout: Some(&pipeline_layout),
        module: &shader,
        entry_point: "main",
    });

    // Encode commands.
    let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
        label: Some("my_custom_kernel_encoder"),
    });
    {
        let mut compute_pass = encoder.begin_compute_pass(&wgpu::ComputePassDescriptor {
            label: Some("my_custom_kernel_pass"),
        });
        compute_pass.set_pipeline(&pipeline);
        compute_pass.set_bind_group(0, &gaussian_buffer.create_bind_group(&device), &[]);
        compute_pass.set_bind_group(1, &output_buffer.create_bind_group(&device), &[]);
        compute_pass.set_push_constants(0, bytemuck::bytes_of(&factor));
        compute_pass.dispatch_workgroups( (gaussian_buffer.size() / 256) as u32, 1, 1);
    }
    queue.submit(Some(encoder.finish()));
}

After creating the kernel file, expose the function in crates/brush-render/src/lib.rs and write a unit test verifying the output buffer values. Update the crate-level documentation using /// comments and add a minimal example to the examples/ folder if applicable.

Summary

  • Fork and clone the repository from github.com/ArthurBrussee/brush, then install Rust ≥ 1.88 with Android and WASM targets.
  • Target the correct crate: use brush-render for GPU kernels, brush-app for UI changes, and brush-js for web improvements.
  • Validate locally by running cargo test --all, cargo fmt, and cargo clippy -- -D warnings before submitting.
  • Build per platform using cargo run --release for desktop, npm run dev for WASM, or cargo ndk for Android.
  • Follow conventions: use conventional commit messages, fill out the PR template, and ensure CI passes in .github/workflows/ci.yml.

Frequently Asked Questions

What Rust version is required to contribute to Brush?

Brush requires Rust 1.88 or newer as specified in the root Cargo.toml. Install it via rustup update stable and ensure you add targets for aarch64-linux-android and wasm32-unknown-unknown if you plan to build for mobile or web platforms.

Which crate should I modify to add a new rendering kernel?

Add new forward rendering kernels to crates/brush-render/src/kernels/ following the pattern in map_gaussians.rs. For back-propagation kernels used during training, use crates/brush-render-bwd/src/kernels/ instead, referencing rasterize_backwards.rs for implementation details.

How do I build the web demo locally?

Navigate to apps/brush-js and run npm run dev. This requires wasm-pack to be installed and the wasm32-unknown-unknown target to be available. The README at apps/brush-js/README.md contains additional build instructions for the Next.js front-end.

How do I run the full CI pipeline locally before submitting a PR?

Execute cargo test --all && cargo bench && npm run build to replicate the GitHub Actions workflow defined in .github/workflows/ci.yml. Running these commands ensures your changes pass formatting, linting, and testing requirements before reviewers examine your pull request.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →