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:
- The
chromium_srcOverride System: During compilation, Brave alters the compiler's include path so that files insrc/brave/chromium_srcare checked before standard Chromium files. This allows Brave developers to intercept#includedirectives, wrap original Chromium classes, and inject custom logic without touching the original file. - Git Patching: When modifying an upstream file is
unavoidable, Brave maintains a series of
.patchfiles. As part of the build process, a script automatically applies these patches to the Chromium source tree before compilation begins. - Build Configuration (GN and Ninja): Chromium uses
GN to generate build files for Ninja. Brave injects its own
.gnand.gniconfiguration 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
(
rustcandcargo). Theadblock-rustcrate 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
cbindgenand thecxxcrate 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::URLLoaderThrottlein 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 theadblock-rustengine. 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++
BraveWalletServiceusing 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.ethereumfor EVM chains andwindow.solanafor Solana—into the webpage. Brave uses a ChromiumRenderFrameObserverin 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
BraveWalletServicein 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.