bare-browser README

The project's README from github.com/BareBrowser/bare-browser. As one markdown file: README.md.

Bare Browser

Shaped by the community

Extensions. Privacy. Freedom

barebrowser.org


Bare is a de-Googled Chromium build for Android, designed to give you more privacy, control and freedom on the web. It strips Google tracking, telemetry and AI integration while keeping powerful features like browser extensions and uBlock Origin. Bare also adds background video playback, the ability to save media from sites that normally block it, support for choosing your preferred download manager, and much more.

It is a patch series rather than a fork: 99 patches against one pinned revision of Chromium Desktop Android, so what this repository holds is exactly the difference between stock Chromium and Bare, and nothing else.

Built and used on a Pixel 10 Pro XL. Not affiliated with Google or the Chromium project.

What you get

Screenshots

Screenshot 1 Screenshot 2
Screenshot 3 Screenshot 4
Screenshot 5 Screenshot 6

Support the project

Bare is one person and one phone. There is no company behind it, nothing in the browser sells you anything, and there is nothing to upsell you to later, which is rather the point of it.

If it is useful to you, you can buy me a coffee. Entirely optional. It buys build hours and a second device to test on, and it changes nothing about the browser either way.

Buy me a coffee

Why

Chromium's Desktop Android build supports real browser extensions, which mobile Chrome does not. That makes it a genuinely better browser to live in, but it still ships Google's AI stack, phones home on a schedule, and hands your links to other apps. Bare fixes that as a patch series rather than a fork, so every change stays readable and reviewable.

What the patches do

Ninety-one patches against one pinned Chromium revision: crash fixes, the extensions toolbar on phone layouts, every Google callback and AI surface removed, and the features Bare adds on top.

The full list, patch by patch, is in docs/patches.md along with what is removed by build flag instead of by patch, and what is deliberately kept.

Network behaviour

Measured on a Pixel 3 running Android 12 and an Android 17 emulator, by watching the sockets opened under Bare's own uid on a wiped profile. What follows is what was actually observed, not what was intended.

On a second and later start, with an established profile, one host is contacted without being asked: update.googleapis.com. That is Chromium's component updater. It is kept deliberately, because the components left registered are the ones that carry security or web compatibility:

Component Why it stays
CRLSet certificate revocation
PKIMetadata Certificate Transparency
SSLErrorAssistant quality of the TLS interstitial
FileTypePolicies download danger classification
OriginTrials web compatibility
Widevine DRM playback
SafetyTips, CrowdDeny lookalike-domain and abusive-notification lists, applied locally

Registration tells Google an install exists, along with a component id, a version, an install date and a cohort. Twelve other components were dropped in patch 0085 for buying nothing here: the Privacy Sandbox set, Google's omnibox suggestion model, the optimization-hints feed, shopping and checkout heuristics, on-device AI history strings, and two Safe Browsing lists that nothing can consult. Three more, ActorSafetyLists, Indigo and CaptchaProvider, are still registered because their purpose is not clear enough in the tree to remove them confidently.

On the first run of a fresh profile there is more, and almost all of it is uBlock Origin fetching the filter lists it ships enabled, from the list maintainers and their CDNs rather than from Google. That happens once and then on the extension's own schedule.

The update check contacts GitHub, and only after the welcome screen has been completed and an update preference stored. It is at most one request a day, to a public release feed, sending User-Agent: Bare/<version> and nothing else: no identifier, no cookies, no version in the request. Choosing manual means nothing leaves the device until the Check for updates row is tapped.

What no longer happens, each verified by re-running the same capture:

Traffic from Android itself and from Google Play Services is separate from all of this and is not affected by anything Bare does.

Safe Browsing does not work in this build, and no longer claims to. Chromium Android performs lookups through a handler that Google injects in its own build and that no public build has. The settings, the Safety Hub module and the promotional cards all described protection that never ran, so patch 0080 removed them. Bare shows no phishing or malware interstitial. Treat unknown links with the caution you would give a browser with no such feature, because that is what this is.

Requirements

Builds run in an x86-64 Ubuntu 22.04 container. On Apple Silicon this means Rosetta emulation, and a full build takes hours.

Build it yourself

Everything runs in the container. The Chromium checkout stays in its volume, because building from a macOS bind mount is slow and unreliable; only small files cross to the host, through exchange/, which is the one directory shared with the container.

1. Start the container.

./builder.sh build
./builder.sh start

2. Put what the build needs where the container can see it.

cp -R patches exchange/
cp third_party/ublock_origin/uBlockOrigin-1.73.0.crx exchange/
tools/version.py gn arm64 > exchange/version-args.gn

3. Fetch Chromium. Inside the container (./builder.sh shell). depot_tools is on the PATH but not installed, so clone it first. This part is Chromium's own procedure rather than anything specific to Bare. See the upstream Android build instructions if a step needs explaining. Expect hours and about 50 GB.

git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git ~/depot_tools
mkdir -p /work/chromium && cd /work/chromium
fetch --nohooks android
cd src
git checkout 945b5115
gclient sync -D --force --reset
./build/install-build-deps.sh --android

4. Apply the series, and drop in the extension. uBlock Origin is kept out of the patches because a 4 MB signed binary as base64 would be unreviewable, so it is copied in separately. Without it the build fails at packaging.

git am /exchange/patches/*.patch
mkdir -p chrome/browser/resources/bare
cp /exchange/uBlockOrigin-1.73.0.crx chrome/browser/resources/bare/ublock_origin.crx

5. Configure. This is the complete configuration the published release was built with, nothing omitted:

target_os = "android"
target_cpu = "arm64"
is_desktop_android = true
is_official_build = true
is_debug = false
is_java_debug = false
is_component_build = false
dcheck_always_on = false
android_static_analysis = "off"
symbol_level = 0
blink_symbol_level = 0
v8_symbol_level = 0
use_remoteexec = false
use_reclient = false

proprietary_codecs = true
ffmpeg_branding = "Chrome"

use_mlkit_for_aicore = false
enable_glic_internal_resources = false
enable_reporting = false
enable_service_discovery = false
enable_mdns = false
enable_arcore = false
enable_cardboard = false
enable_openxr = false

chrome_public_manifest_package = "org.barebrowser"
android_override_version_code = "801000035"
android_override_version_name = "1.0.0-alpha.2"

The last two lines are what tools/version.py gn arm64 emits, and they matter: they are written into the manifest, so a build without them will not match the release.

The 32-bit build differs in exactly three lines: target_cpu = "arm", the version code 801000020 that tools/version.py gn arm emits, and clang_use_default_sample_profile = false, which stops GN demanding an AFDO profile this checkout never syncs.

mkdir -p out/Bare
$EDITOR out/Bare/args.gn          # paste the block above
gn gen out/Bare
autoninja -C out/Bare chrome_public_apk

6. Compare. Your APK will not be byte-identical to the published one, because that one carries a signature only its key can produce. Everything else should match:

tools/apk-content-hash.py out/Bare/apks/ChromePublic.apk Bare-1.0.0-alpha.1.apk

See BUILDING.md for the rest of the workflow, including versioning and how releases are signed.

Verifying a build

Three questions, and they have different answers.

Is this the file that was published? Compare its SHA-256 against the one on the release page. That catches a truncated or tampered download and nothing else: the hash is published by the same person as the file, so on its own it proves nothing about where the file came from.

Is it genuinely Bare? Check who signed it. Nothing signed by any other key is Bare.

apksigner verify --print-certs Bare-1.0.0-alpha.1.apk
SHA-256  ae:2a:0e:7f:b7:a1:32:ec:51:7d:26:a8:e7:c8:3d:27
         5e:83:74:7b:0a:77:7d:4a:42:22:5b:1d:34:32:71:a0
subject  CN=Bare Browser, O=Bare Browser, OU=Release
key      RSA 4096

Releases before v1.0.0-alpha.1 were signed with Chromium's debug key, which is checked into Chromium's tree and therefore public. Anyone can build an APK that installs as an update over one of those. If you are running a Chromium Extend build, uninstall it rather than updating; a Bare release cannot replace it in place anyway, because the signing identity deliberately changed.

Can you rebuild it yourself? Yes, and that is the only one of the three that proves where a binary came from. The signature is deliberately not reproducible, since nobody but the key holder can produce it, but everything else is. Follow Build it yourself exactly, including the version arguments, then compare:

tools/apk-content-hash.py out/Bare/apks/ChromePublic.apk Bare-1.0.0-alpha.1.apk

It hashes every entry except the signature, so two builds of the same source agree whoever signed them. What has been measured, and what has not.

Known limitations

Not done yet

Each has an exact file and line reference in docs/stage-1-2.md:

bare-browser (BareBrowser/bare-browser)

Searching Database…

What is this?Bare is a de-Googled Chromium build for Android that strips Google tracking, telemetry, and AI integration while keeping browser extensions and uBlock Origin working, and adds things like background video playback and media saving.
Is Bare a fork of Chromium or something else?It's a patch series, not a fork: 99 patches applied against one pinned revision of Chromium's Desktop Android build, so the repo only contains the diff between stock Chromium and Bare.
How do I get Bare on my phone?Download the signed APK from the release page and verify its SHA-256 hash, or build it yourself from source inside the provided Docker container by applying the patch series to a pinned Chromium checkout.
Does forcing all links to stay in-browser cause problems?Yes — the patch that keeps http(s) navigations inside Bare instead of handing them to other apps is described as blunt, so some OAuth flows and deep links that expect an app handoff no longer work.
Does Bare phone home at all?Two things still reach a server on their own: Chromium's component updater contacting update.googleapis.com for security-relevant components like CRLSet and Widevine, and Bare's own update check against GitHub, which happens at most once a day and only sends a bare User-Agent string.
Why does Bare keep uBlock Origin's full version instead of the Manifest V3 Lite one?Bare's Desktop Android base still supports Manifest V2, so it ships the full uBlock Origin exactly as its author publishes it, instead of the crippled Manifest V3 Lite version most mobile Chromium browsers are forced into.
How can I verify a downloaded APK is genuinely Bare and not tampered with?Check the APK's SHA-256 against the release page, confirm it's signed with Bare's RSA 4096 release key (a different identity than Chromium's public debug key used before v1.0.0-alpha.1), or rebuild it yourself and compare everything except the signature.
What Chromium version and device is Bare built on?It patches Chromium 153.0.7999.0 (commit 945b5115) targeting arm64 Desktop Android, and is actively built and tested on a Pixel 10 Pro XL.
Size
22.6 MB
Stars
517
Age
2mo
Commits · 90 Days