# How Rust Is Integrated into Brave: The adblock-rust FFI Architecture

> Discover how Brave integrates Rust via C FFI, compiling adblock-rust into a static library for C++ consumption. Learn about the FFI architecture.

- Repository: [Brave Software/brave-browser](https://github.com/brave/brave-browser)
- Tags: internals
- Published: 2026-02-16

---

**Brave integrates Rust through a C-style Foreign Function Interface (FFI) that compiles the adblock-rust crate into a static library, exposing C bindings that Brave's C++ code consumes through a thin wrapper layer.**

Brave Browser leverages Rust for its core ad-blocking engine via the `adblock-rust` library, bridging the performance and memory-safety benefits of Rust with Chromium's existing C++ codebase. This integration relies on a carefully structured FFI layer that compiles Rust code into static libraries callable from Brave's native components.

## The Three-Layer Architecture of adblock-rust Integration

Brave's Rust integration consists of three distinct layers that separate concerns between the Rust implementation and the C++ browser code.

### 1. Pure Rust Crate (adblock_rust)

The core logic resides in `components/adblock_rust/`, a standard Cargo project that implements filter parsing, cosmetic filtering, and network rule evaluation. This crate knows nothing about Chromium or C++.

**Key file:** [`components/adblock_rust/Cargo.toml`](https://github.com/brave/brave-browser/blob/main/components/adblock_rust/Cargo.toml) defines the library target and dependencies.

### 2. FFI Bindings (adblock_rust_ffi)

This layer generates a thin C API around the Rust crate. The bindings are compiled into a static library (`libadblock_rust_ffi.a`) and linked into the Chromium build.

**Key files:**
- [`components/adblock_rust_ffi/README.md`](https://github.com/brave/brave-browser/blob/main/components/adblock_rust_ffi/README.md) – Overview and build instructions
- [`components/adblock_rust_ffi/adblock_rust_ffi.h`](https://github.com/brave/brave-browser/blob/main/components/adblock_rust_ffi/adblock_rust_ffi.h) – C header exposing Rust functions

### 3. C++ Wrapper (adblock_engine.cc)

The final layer provides a C++-friendly façade used by Brave's UI and network stack. It translates Chromium's `GURL` objects into FFI-friendly types and manages object lifetimes.

**Key file:** `components/adblock_rust_ffi/adblock_engine.cc` implements the RAII wrapper around the C API.

## Build System: Compiling Rust into Brave

Brave uses GN (Generate Ninja) to orchestrate the build, integrating Cargo through custom rules that compile Rust code into static libraries linkable by Chromium.

### Step 1: Cargo Builds the Rust Crate

The `components/adblock_rust/BUILD.gn` file invokes the `rust_static_library` rule, which runs `cargo build` to produce `libadblock_rust.a`.

### Step 2: FFI Wrapper Generation

The `adblock_rust_ffi` component contains a small [`lib.rs`](https://github.com/brave/brave-browser/blob/main/lib.rs) that re-exports needed symbols with `#[no_mangle] extern "C"` attributes. GN builds this via `rust_static_library` → `static_library` → `libadblock_rust_ffi.a`.

### Step 3: Linking into Chromium

The resulting static library links into the `brave_adblock` target, making symbols available to C++ code throughout the browser.

## The FFI Layer: C API Exported from Rust

The FFI header exposes a minimal C interface that hides Rust's complexity behind opaque pointers and primitive types.

```c
/* components/adblock_rust_ffi/adblock_rust_ffi.h */
#ifdef __cplusplus
extern "C" {
#endif

/* Create a new engine from newline-separated filter text.
 * Returns an opaque pointer to the Rust Engine. */
void* adblock_engine_new(const char* filters);

/* Check if a request should be blocked.
 * Returns 1 for blocked, 0 for allowed. */
int adblock_engine_check(void* engine,
                         const char* url,
                         const char* source_url);

/* Release the engine and free memory. */
void adblock_engine_free(void* engine);

#ifdef __cplusplus
}
#endif

```

These functions use `#[no_mangle]` attributes in the Rust source to ensure symbol names remain stable across the FFI boundary.

## C++ Integration: Consuming the FFI in Brave

Brave's C++ code wraps the C API in a RAII class that manages the opaque pointer automatically.

```cpp
// components/adblock_rust_ffi/adblock_engine.cc
#include "components/adblock_rust_ffi/adblock_rust_ffi.h"

class AdBlockEngine {
 public:
  explicit AdBlockEngine(const std::string& filters) {
    raw_engine_ = adblock_engine_new(filters.c_str());
  }

  ~AdBlockEngine() {
    if (raw_engine_) {
      adblock_engine_free(raw_engine_);
    }
  }

  bool ShouldBlock(const GURL& request_url, const GURL& source_url) {
    int result = adblock_engine_check(
        raw_engine_,
        request_url.spec().c_str(),
        source_url.spec().c_str());
    return result != 0;
  }

 private:
  void* raw_engine_ = nullptr;
};

```

This wrapper translates Chromium's `GURL` objects into C strings and ensures the Rust engine is properly freed when the C++ object goes out of scope.

## Code Examples: Using the Adblock Engine

### Example 1: Creating the Engine

```cpp
#include "components/adblock_rust_ffi/adblock_engine.h"

std::unique_ptr<AdBlockEngine> CreateEngine(
    const std::vector<std::string>& raw_filters) {
  // Join filter lists into newline-separated text
  std::string joined;
  for (const auto& filter : raw_filters) {
    joined += filter + "\n";
  }

  void* raw_engine = adblock_engine_new(joined.c_str());
  if (!raw_engine) {
    LOG(ERROR) << "Failed to instantiate adblock engine";
    return nullptr;
  }

  return std::make_unique<AdBlockEngine>(raw_engine);
}

```

*Source:* `components/adblock_rust_ffi/adblock_engine.cc`

### Example 2: Checking a Network Request

```cpp
bool ShouldBlockRequest(AdBlockEngine* engine,
                        const GURL& request_url,
                        const GURL& source_url) {
  // Convert GURL to UTF-8 C strings
  std::string req = request_url.spec();
  std::string src = source_url.spec();

  int blocked = adblock_engine_check(engine->raw_ptr(),
                                     req.c_str(),
                                     src.c_str());
  return blocked != 0;
}

```

### Example 3: Integrating with Brave Shields UI

```cpp
void BraveShieldsHandler::OnToggleAdBlocking(bool enabled) {
  if (enabled) {
    // Load filter lists from disk
    std::vector<std::string> lists = LoadFilterLists();
    adblock_engine_ = CreateEngine(lists);
  } else {
    adblock_engine_.reset();  // Calls adblock_engine_free internally
  }
}

```

*Source:* `browser/brave_shields_handler.cc`

## Summary

- **Three-layer architecture:** Pure Rust crate (`adblock_rust`), C FFI bindings (`adblock_rust_ffi`), and C++ wrapper (`adblock_engine.cc`).
- **Static linking:** The Rust code compiles into `libadblock_rust_ffi.a` and links directly into the Chromium binary, avoiding runtime overhead.
- **Minimal FFI surface:** The C API exposes only three core functions (`adblock_engine_new`, `adblock_engine_check`, `adblock_engine_free`) to minimize unsafe boundary risks.
- **RAII wrapper:** C++ code manages the opaque Rust pointer through `AdBlockEngine`, ensuring automatic cleanup when the browser destroys the profile.
- **Cross-platform:** The same Rust crate builds for Windows, macOS, Linux, Android, and iOS using Brave's GN/Cargo integration.

## Frequently Asked Questions

### How does Brave call Rust code from C++?

Brave uses a C-style Foreign Function Interface (FFI) that exposes Rust functions with `#[no_mangle] extern "C"` attributes. The C++ code includes [`adblock_rust_ffi.h`](https://github.com/brave/brave-browser/blob/main/adblock_rust_ffi.h) and calls functions like `adblock_engine_new()` and `adblock_engine_check()`, which are linked from the static library `libadblock_rust_ffi.a` compiled by Cargo.

### Why does Brave use FFI instead of rewriting everything in Rust?

Brave builds on top of Chromium, which contains millions of lines of C++ code. Rewriting the entire browser in Rust would be impractical and would complicate merging upstream Chromium updates. The FFI approach allows Brave to incrementally adopt Rust for specific components—like the ad-blocking engine—while maintaining the existing C++ infrastructure and update mechanisms.

### What is the performance impact of the FFI layer?

The performance impact is negligible because the FFI uses static linking and a minimal C API surface. The Rust code compiles into a native static archive (`libadblock_rust_ffi.a`) that links directly into the Chromium binary, eliminating dynamic linking overhead. The C functions accept primitive types and pointers, avoiding complex marshalling costs during the critical path of network request filtering.

### Where are the adblock-rust source files located?

The source files reside in the `brave-core` submodule under `src/brave`. The pure Rust implementation lives in `components/adblock_rust/`, while the FFI bindings and C++ wrapper are in `components/adblock_rust_ffi/`. The top-level `brave-browser` repository references these components as a submodule, with build instructions available in [`components/adblock_rust_ffi/README.md`](https://github.com/brave/brave-browser/blob/main/components/adblock_rust_ffi/README.md).