How Brave Customizes Chromium for Ad Blocking and Crypto

This article provides a technical overview of how the Brave browser modifies the open-source Chromium codebase to integrate native features. It covers the architectural strategy Brave uses to patch Chromium without breaking upstream updates, the Foreign Function Interface (FFI) pipeline used to embed a Rust-based ad-blocking engine into a C++ browser, and the multi-process architecture utilized to build a native cryptocurrency wallet directly into the browser core.

The Chromium Customization Strategy

Chromium consists of tens of millions of lines of C++ code that update constantly. If Brave simply forked Chromium and rewrote the core files, merging upstream security patches from Google would quickly become impossible. To solve this, Brave isolates its modifications in a separate repository called brave-core, which is mounted at src/brave inside the standard Chromium source tree.

Brave modifies Chromium's behavior using three primary mechanisms:

  1. The chromium_src Override System: During compilation, Brave alters the compiler's include path so that files in src/brave/chromium_src are checked before standard Chromium files. This allows Brave developers to intercept #include directives, wrap original Chromium classes, and inject custom logic without touching the original file.
  2. Git Patching: When modifying an upstream file is unavoidable, Brave maintains a series of .patch files. As part of the build process, a script automatically applies these patches to the Chromium source tree before compilation begins.
  3. Build Configuration (GN and Ninja): Chromium uses GN to generate build files for Ninja. Brave injects its own .gn and .gni configuration files into the build pipeline, instructing the compiler to include Brave-specific C++ and Rust source files alongside the standard browser components.

Embedding the Rust-Based Ad Blocker

Standard ad blockers operate as browser extensions, relying on JavaScript APIs that introduce performance bottlenecks and memory overhead. Brave bypasses the extension system entirely by embedding an ad-blocking engine called adblock-rust directly into the browser's C++ network stack.

Because Chromium is written in C++ and the ad blocker is written in Rust, Brave bridges the two languages using a Foreign Function Interface (FFI):

  • Compilation and Linking: Brave extends Chromium’s GN build system with custom templates that invoke the Rust compiler (rustc and cargo). The adblock-rust crate is compiled into a static library, which the Ninja build system then links directly into the main browser binary.
  • The FFI Bridge: Brave uses tools like cbindgen and the cxx crate to automatically generate C++ header files for the Rust code. This exposes Rust structs and functions in a format that Chromium’s C++ compiler can understand and execute safely.
  • Network Interception: In Chromium, network requests are managed by the Network Service. Brave implements a custom content::URLLoaderThrottle in C++. Before Chromium dispatches any network request (such as loading an image, script, or tracking pixel), it passes through this throttle. The C++ throttle takes the request URL, origin, and resource type, and passes them across the FFI boundary to the adblock-rust engine. The Rust engine evaluates the request against memory-mapped filter lists in microseconds and returns a boolean decision to the C++ code, which then either allows, blocks, or redirects the request before a network connection is ever made.

Integrating the Native Cryptocurrency Wallet

Like its ad blocker, the Brave Wallet is built natively into the browser rather than running as a downloadable Web3 extension. This eliminates the risk of extension-spoofing and reduces CPU and RAM usage. Embedding a crypto wallet requires deep integration with Chromium’s multi-process security model, which separates the unprivileged "Renderer" processes (which run websites) from the privileged "Browser" process (which has access to the operating system and disk).

Brave achieves this through the following architecture:

  • The Core Service: The heart of the wallet is the BraveWalletService, a C++ component that runs securely inside the privileged Browser process. This service manages encrypted state, handles RPC communications with blockchain nodes, and coordinates transaction signing.
  • Rust for Cryptography: Cryptocurrency wallets require complex cryptographic operations, such as hierarchical deterministic (HD) key derivation and elliptic curve signing. To ensure memory safety when handling private keys, Brave offloads many of these cryptographic primitives to Rust crates, linking them to the C++ BraveWalletService using the same FFI pipeline used by the ad blocker.
  • Web3 Provider Injection: For decentralized applications (dApps) to detect the wallet, the browser must inject JavaScript objects—such as window.ethereum for EVM chains and window.solana for Solana—into the webpage. Brave uses a Chromium RenderFrameObserver in the Renderer process to monitor when a new webpage context is created. It then uses Chromium's Gin library to bind native C++ functions to these JavaScript objects.
  • Mojo Inter-Process Communication (IPC): Because the webpage runs in the untrusted Renderer process and the wallet lives in the secure Browser process, they cannot share memory directly. When a user clicks "Connect Wallet" on a website, the injected JavaScript calls the C++ binding in the Renderer. The Renderer then sends a message across Chromium’s native IPC system, known as Mojo. The BraveWalletService in the Browser process receives the Mojo message, triggers the native C++ browser UI to ask for user permission, signs the data, and sends the cryptographic response back through the Mojo pipe to the webpage.