Overview
Helium uses a patch-based development model inherited from ungoogled-chromium. Instead of maintaining a forked Chromium repository, all modifications are stored as unified diff patches in GNU Quilt format.
Why Patches?
Upstream Compatibility Easy to rebase on new Chromium versions by reapplying patches
Clear Attribution Each patch is clearly sourced (ungoogled-chromium, Brave, Helium, etc.)
Modular Changes Individual features can be enabled/disabled by including/excluding patches
Review-Friendly Changes are isolated and easy to review individually
Patch Directory Structure
Patches are organized by source and category:
patches/
├── series # Defines patch application order
├── upstream-fixes/ # Backported fixes from Chromium
│ └── vertical/ # Vertical tabs feature patches
├── inox-patchset/ # Privacy patches from Inox
├── iridium-browser/ # Privacy patches from Iridium
├── ungoogled-chromium/ # Core degoogling patches
├── bromite/ # Fingerprinting protection
├── brave/ # Import and tab features
├── debian/ # Debian-specific patches
└── helium/
├── core/ # Core Helium functionality
│ ├── search/ # Search engine configuration
│ └── noise/ # Fingerprinting noise
├── settings/ # Settings page modifications
├── hop/ # Password manager replacement
└── ui/ # User interface changes
└── layout/ # Layout system changes
The Series File
The patches/series file defines the order in which patches are applied:
# Upstream fixes first
upstream-fixes/missing-dependencies.patch
upstream-fixes/vertical/r1568708-fix-crash-during-collapsed-tabgroup-drag.patch
...
# Then third-party privacy patches
inox-patchset/fix-building-without-safebrowsing.patch
inox-patchset/disable-autofill-download-manager.patch
...
# Finally Helium patches
helium/core/add-zen-importer.patch
helium/core/services-prefs.patch
...
Patch order matters! Later patches may depend on earlier ones. Always maintain the order defined in series.
Applying Patches
Use the patches.py utility to apply patches:
Basic Application
# Apply all patches from patches/series
python3 utils/patches.py apply chromium patches
Advanced Options
Strict Mode
Custom Patch Directory
Custom Patch Binary
# Apply without fuzz (fail if patches don't apply exactly)
python3 utils/patches.py apply chromium patches --no-fuzz
Dry Run Testing
Test if patches will apply cleanly without modifying files:
from pathlib import Path
from utils.patches import dry_run_check
patch_path = Path( 'patches/helium/core/services-prefs.patch' )
tree_path = Path( 'chromium' )
code, stdout, stderr = dry_run_check(patch_path, tree_path)
if code == 0 :
print ( "Patch will apply cleanly" )
else :
print ( f "Patch failed: { stderr } " )
Creating New Patches
Make Changes
Edit files in the Chromium source tree: cd chromium
# Make your changes to source files
vim src/chrome/browser/ui/browser.cc
Generate Diff
Create a unified diff of your changes: # From inside the chromium directory
git diff > ../patches/helium/core/my-new-feature.patch
Add to Series
Add your patch to patches/series in the appropriate location: # Edit patches/series
vim ../patches/series
# Add your patch line:
# helium/core/my-new-feature.patch
Test Application
Verify your patch applies cleanly: cd ..
# Reset changes
cd chromium
git checkout .
cd ..
# Apply all patches including your new one
python3 utils/patches.py apply chromium patches
Build and Test
Build Helium and test your changes: cd chromium
ninja -C out/Default chrome
./out/Default/chrome
Patches use the unified diff format:
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -150,6 +150,10 @@ Browser::Browser(const CreateParams& params)
tab_strip_model_delegate_(std::make_unique<BrowserTabStripModelDelegate>(this)),
tab_menu_model_delegate_(std::make_unique<BrowserTabMenuModelDelegate>(this)) {
+ // Helium: Set custom window title
+ if (params.type == TYPE_NORMAL) {
+ override_window_title_ = "Helium";
+ }
// Set up the app_controller_ before calling Init() so that it will be available
// for any code that runs during initialization.
--- a/path/to/file.cc # Original file path (a/ prefix)
+++ b/path/to/file.cc # Modified file path (b/ prefix)
@@ -150,6 +150,10 @@ # Hunk header: line numbers and context
@@ -150,6 means original file, starting at line 150, showing 6 lines
+150,10 means modified file, starting at line 150, showing 10 lines
Lines starting with - are removed
Lines starting with + are added
Lines starting with space are context (unchanged)
Modifying Existing Patches
Apply Patches Up To Target
Apply all patches before the one you want to modify: # Manually apply patches in order until the one before yours
# Or create a temporary series file
head -n 100 patches/series > patches/series.tmp
python3 utils/patches.py apply chromium patches/series.tmp
Make Changes
Edit the files affected by the patch you want to modify
Regenerate Patch
Create an updated patch: cd chromium
git diff > ../patches/helium/core/my-patch.patch
Verify
Test that all patches still apply in order: cd chromium
git checkout . # Reset all changes
cd ..
python3 utils/patches.py apply chromium patches
When modifying patches, ensure subsequent patches don’t conflict with your changes. You may need to update multiple patches if they affect the same files.
Patch Categories Explained
Upstream Fixes (48 patches)
Backported features from newer Chromium versions:
upstream-fixes/vertical/ # Vertical tabs implementation
├── r1568708-fix-crash-during-collapsed-tabgroup-drag.patch
├── r1570045-improve-dragging-between-groups-and-unpinned.patch
└── ... (45 more patches)
These patches are prefixed with rXXXXXXX indicating the Chromium revision they came from.
ungoogled-chromium (46 patches)
Core privacy and degoogling features:
disable-crash-reporter.patch
disable-google-host-detection.patch
disable-gcm.patch
disable-domain-reliability.patch
block-trk-and-subdomains.patch
Disable Google services and tracking connections.
disable-gaia.patch # No Google account sync
disable-profile-avatar-downloading.patch
disable-privacy-sandbox.patch
disable-webrtc-log-uploader.patch
Disable features that compromise privacy.
add-components-ungoogled.patch
add-ipv6-probing-option.patch
add-flag-to-configure-extension-downloading.patch
add-flag-for-search-engine-collection.patch
add-flag-to-force-punycode-hostnames.patch
Add command-line flags for privacy customization.
Helium Core (85 patches)
Helium-specific functionality:
Services & Integration
Search
Privacy Enhancements
Features
helium/core/services-prefs.patch # Helium Services integration
helium/core/onboarding-page.patch # Welcome page
helium/core/change-chromium-branding.patch # Rebrand to Helium
helium/core/ublock-install-as-component.patch
helium/core/ublock-helium-services.patch
helium/core/search/restore-google.patch
helium/core/search/engine-defaults.patch
helium/core/search/fix-search-engine-icons.patch
helium/core/search/force-eu-search-features.patch
helium/core/noise/core.patch # Base fingerprinting noise
helium/core/noise/canvas.patch # Canvas fingerprinting
helium/core/noise/audio.patch # AudioContext fingerprinting
helium/core/noise/hardware-concurrency.patch
helium/core/reduce-accept-language-headers.patch
helium/core/disable-ad-topics-and-etc.patch
helium/core/add-native-bangs.patch # DuckDuckGo-style !bangs
helium/core/split-view.patch # Window split view
helium/core/tab-cycling-mru.patch # MRU tab switching
helium/core/enable-parallel-downloading.patch
helium/core/infinite-tab-freezing.patch
Helium UI (86 patches)
User interface modifications:
helium/ui/
├── layout/ # Core layout system
│ ├── core.patch
│ ├── settings.patch
│ ├── compact.patch
│ └── vertical.patch
├── location-bar.patch # Address bar design
├── omnibox.patch # Omnibox functionality
├── tabs.patch # Tab styling
├── toolbar.patch # Toolbar design
├── app-menu-*.patch # Application menu
└── helium-color-scheme.patch # Color theme
Validating Patches
Use the development utilities to validate patches:
# Validate all patches apply cleanly
./devutils/validate_patches.py -l chromium -v
# Check patches follow style guidelines
python3 -m pylint patches/ * .py
Merging Patch Directories
Combine patches from multiple sources:
# Merge two patch directories
python3 utils/patches.py merge \
destination_patches \
source1_patches \
source2_patches
# Prepend patches to existing directory
python3 utils/patches.py merge \
--prepend \
existing_patches \
new_patches
Best Practices
Keep Patches Small Each patch should implement one logical change. Easier to review, debug, and maintain.
Document Changes Add comments in patch files explaining why changes were made: + // Helium: Disable password manager
+ // We use our own password management solution
+ return false;
Test Patch Order After adding/modifying patches, always test that all patches apply cleanly in series order.
Attribution If a patch is based on work from another project, note it in the patch filename or header.
Troubleshooting
Patch Doesn’t Apply
# Check which files are conflicting
python3 utils/patches.py apply chromium patches --no-fuzz
# Look for:
# "Hunk #1 FAILED at line 150"
# This means the code context changed
Solutions:
Manually update the patch context to match current code
Regenerate the patch from scratch
Check if upstream Chromium changed the affected code
Patches Apply But Build Fails
# Check if all required patches are present
grep "^helium/core/" patches/series
# Verify patch order
cat patches/series | grep -A5 -B5 "your-patch.patch"
Common causes:
Patch depends on another patch that wasn’t applied
Patch conflicts with a later patch
Build configuration doesn’t match patched code
Fuzz Warnings
patching file chrome/browser/ui/browser.cc
Hunk #1 succeeded at 152 (offset 2 lines).
Fuzz means the patch applied but line numbers didn’t match exactly. Usually safe, but verify the changes are correct.
CI Patch Validation
Helium’s CI automatically validates patches:
# From .cirrus.yml
validate_patches_script :
- ./devutils/validate_patches.py -l chromium_src -v
This ensures:
All patches in series file exist
Patches apply cleanly to the target Chromium version
No syntax errors in patch files
Correct file paths in patches
Next Steps
Development Overview Learn about Helium’s overall architecture
Building Helium Build Helium with your modified patches