# How Dependencies Are Managed in the Brush Project: Cargo, npm, and Gradle

> Discover how the brush project manages dependencies using Cargo for Rust, npm for JavaScript, and Gradle for Android. Optimize your polyglot development workflow effectively.

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

---

**The brush project uses a polyglot dependency management strategy with Cargo for Rust crates, npm for JavaScript frontends, and Gradle with Maven for the Android application, all coordinated through a shared workspace configuration.**

The `ArthurBrussee/brush` repository is a multi-platform 3D Gaussian splatting tool that combines Rust, TypeScript, and Android components. Because it spans multiple languages and targets, the project employs distinct package managers for each toolchain while maintaining consistency through workspace-level configuration files. Understanding how dependencies are structured across these environments is essential for contributing to or extending the codebase.

## Rust Dependencies with Cargo

The Rust components of the brush project use **Cargo** as the native package manager, organized as a workspace defined in the root [`Cargo.toml`](https://github.com/ArthurBrussee/brush/blob/main/Cargo.toml).

### Workspace Configuration

The top-level [`Cargo.toml`](https://github.com/ArthurBrussee/brush/blob/main/Cargo.toml) establishes a shared configuration for all member crates using the `[workspace]` section. This file defines global settings including `edition`, `version`, `license`, and `repository` that propagate to every crate in the `crates/` directory. Individual crates such as `brush-train`, `brush-viewer`, and `brush-render` declare their specific dependencies in their respective [`Cargo.toml`](https://github.com/ArthurBrussee/brush/blob/main/Cargo.toml) files, enabling fine-grained control while sharing common metadata.

### Patch Overrides for Forked Dependencies

The workspace uses Cargo's patch functionality to override upstream crates with custom forks. The root [`Cargo.toml`](https://github.com/ArthurBrussee/brush/blob/main/Cargo.toml) contains `[patch.crates-io]` and `[patch."https://github.com/tracel-ai/cubecl"]` sections that redirect dependencies like `wgpu` and `cubecl` to GitHub forks maintained by the project maintainers. This ensures critical bug fixes or API modifications are available across all workspace members without modifying each crate's individual dependency list.

### Adding Rust Dependencies

To add a new dependency to a specific crate, modify its individual [`Cargo.toml`](https://github.com/ArthurBrussee/brush/blob/main/Cargo.toml) file:

```toml

# In crates/brush-train/Cargo.toml

[dependencies]
nalgebra = { version = "0.33", features = ["serde"] }

```

For workspace-wide dependencies that multiple crates share, add them to the `[workspace.dependencies]` section in the root [`Cargo.toml`](https://github.com/ArthurBrussee/brush/blob/main/Cargo.toml), then reference them in individual crates using `workspace = true`.

## JavaScript Dependencies with npm

The JavaScript and TypeScript components, including the `brush-js` frontend and CLI tools, use **npm** for package management.

The root [`package.json`](https://github.com/ArthurBrussee/brush/blob/main/package.json) contains the dependency manifest for Node.js tooling including `typescript`, `vite`, and `react`. Runtime and build dependencies are resolved into `node_modules/` when running `npm install`, `pnpm install`, or `yarn`.

To add a new frontend library:

```bash
npm install lodash@4.17.21

```

This updates the [`package.json`](https://github.com/ArthurBrussee/brush/blob/main/package.json) automatically:

```json
{
  "dependencies": {
    "lodash": "^4.17.21",
    "react": "^18.3.0"
  }
}

```

## Android Dependencies with Gradle

The Android application located in `apps/brush-app` uses **Gradle** with Maven-style coordinates to manage Java and Kotlin dependencies.

The `build.gradle` file declares dependencies using the `implementation` configuration, pulling artifacts from Maven repositories including Google and Maven Central. Key dependencies include AndroidX libraries and the Rerun SDK for visualization.

To add a new Android dependency, edit `apps/brush-app/build.gradle`:

```gradle
dependencies {
    implementation "androidx.appcompat:appcompat:1.6.1"
    implementation "com.github.rerun:rerun-sdk:0.31.0"
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.0"
}

```

## WebAssembly and Cross-Platform Crates

WebAssembly builds rely on Cargo with specific WASM-targeting crates such as `wasm-bindgen` and `wasm-streams`. These dependencies are declared in the workspace [`Cargo.toml`](https://github.com/ArthurBrussee/brush/blob/main/Cargo.toml) and individual crate configurations like [`crates/brush-render-bwd/Cargo.toml`](https://github.com/ArthurBrussee/brush/blob/main/crates/brush-render-bwd/Cargo.toml). This ensures the Rust code compiles correctly for browser targets while sharing the same dependency resolution logic as native builds.

## Summary

- The brush project uses **Cargo** for Rust workspace management with centralized versioning in the root [`Cargo.toml`](https://github.com/ArthurBrussee/brush/blob/main/Cargo.toml) and per-crate dependency lists.
- **Patch overrides** in the workspace configuration allow custom forks of critical crates like `wgpu` and `cubecl` to be used project-wide.
- **npm** handles JavaScript/TypeScript dependencies through the root [`package.json`](https://github.com/ArthurBrussee/brush/blob/main/package.json) for frontend tooling and web interfaces.
- **Gradle** manages Android-specific dependencies in `apps/brush-app/build.gradle` using Maven coordinates from Google and Maven Central repositories.
- Each toolchain maintains isolation while the workspace structure ensures consistent versioning and build compatibility across platforms.

## Frequently Asked Questions

### Does the brush project use a single package manager for all components?

No. The project uses language-specific package managers: Cargo for Rust crates, npm for JavaScript/TypeScript frontend code, and Gradle for the Android application. This polyglot approach allows each component to use its native ecosystem while the workspace structure coordinates version metadata across Rust crates.

### How do I override a Rust dependency with a custom fork in the brush project?

Add a `[patch.crates-io]` section to the root [`Cargo.toml`](https://github.com/ArthurBrussee/brush/blob/main/Cargo.toml) file. Specify the crate name and the Git URL of your fork, optionally including a specific branch or commit hash. This override applies to all workspace members that depend on that crate, ensuring consistency without editing individual [`Cargo.toml`](https://github.com/ArthurBrussee/brush/blob/main/Cargo.toml) files in the `crates/` directory.

### Where are JavaScript dependencies installed in the brush repository?

JavaScript and TypeScript dependencies are declared in the root [`package.json`](https://github.com/ArthurBrussee/brush/blob/main/package.json) and installed into the `node_modules/` directory at the repository root when running `npm install`. This configuration supports the web-based frontend and CLI tooling included in the project.

### Can I use workspace dependencies for Android Gradle builds?

No, the Android Gradle build in `apps/brush-app/build.gradle` operates independently from the Cargo workspace. Android dependencies use Maven coordinates and must be added directly to the Gradle build script, though the project maintains consistent versioning manually across Cargo and Gradle where libraries have Java/Kotlin equivalents.