Recompile Chromium with JavaScript, Cookies, Notifications and Profiles disabled, with Claude's help
I recompiled Chromium with JavaScript, Cookies, Notifications and Profiles disabled. No cookies, no cookie banners, no tracking, no nonsense. A nicer Lynx with a GUI.
Here are the steps to follow, naturally, on Linux - in my case a Fedora based Toolbx container:
Install build dependencies:
sudo dnf install gperf flex bison clang lld llvm ninja-build nodejs npm python3 java-11-openjdk-headless libdrm-devel libxkbcommon-devel mesa-libgbm-devel pango-devel cairo-devel alsa-lib-devel cups-devel dbus-devel gtk3-devel nss-devel libXtst-devel libXdamage-develClone and initialize depo_tools:
cd ~
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
export PATH="$PATH:$HOME/depot_tools"
gclientClone Chromium:
mkdir chromium && cd chromium
fetch --no-history chromium
Generate build config:
cd src
gn gen out/Default --args='is_debug=false is_component_build=true symbol_level=0 blink_symbol_level=0'Write this patch generated with Claude's Opus 4.5 help to a file named decrapify.patch:
diff --git a/chrome/browser/notifications/notification_permission_context.cc b/chrome/browser/notifications/notification_permission_context.cc
index 9bab2508a6..50ec9c8d12 100644
--- a/chrome/browser/notifications/notification_permission_context.cc
+++ b/chrome/browser/notifications/notification_permission_context.cc
@@ -143,6 +143,12 @@ ContentSetting NotificationPermissionContext::GetPermissionStatusForExtension(
void NotificationPermissionContext::DecidePermission(
std::unique_ptr<permissions::PermissionRequestData> request_data,
permissions::BrowserPermissionCallback callback) {
+
+ std::move(callback).Run(content::PermissionResult(
+ blink::mojom::PermissionStatus::DENIED,
+ content::PermissionStatusSource::UNSPECIFIED));
+ return;
+
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
// Permission requests for either Web Notifications and Push Notifications may
diff --git a/chrome/browser/translate/translate_service.cc b/chrome/browser/translate/translate_service.cc
index 0f1d12b75d..2e02cfff5f 100644
--- a/chrome/browser/translate/translate_service.cc
+++ b/chrome/browser/translate/translate_service.cc
@@ -142,14 +142,7 @@ bool TranslateService::IsTranslatableURL(const GURL& url) {
// - about:blank
// - Chrome OS file manager extension
// Note: Keep in sync with condition in TranslateAgent::PageCaptured.
- return !url.is_empty() && !url.SchemeIs(content::kChromeUIScheme) &&
- !url.SchemeIs(chrome::kChromeNativeScheme) &&
- !url.SchemeIs(content::kChromeDevToolsScheme) &&
-#if BUILDFLAG(IS_CHROMEOS)
- !(url.SchemeIs(extensions::kExtensionScheme) &&
- url.DomainIs(file_manager::kFileManagerAppId)) &&
-#endif
- !url.IsAboutBlank();
+return false;
}
bool TranslateService::IsAvailable(PrefService* prefs) {
diff --git a/chrome/browser/ui/views/profiles/profile_picker_view.cc b/chrome/browser/ui/views/profiles/profile_picker_view.cc
index e7d1b55897..800a728c30 100644
--- a/chrome/browser/ui/views/profiles/profile_picker_view.cc
+++ b/chrome/browser/ui/views/profiles/profile_picker_view.cc
@@ -165,22 +165,7 @@ void ClearLockedProfilesFirstBrowserKeepAlive() {
// static
void ProfilePicker::Show(Params&& params) {
- // Re-open with new params if necessary.
- if (g_profile_picker_view && g_profile_picker_view->MaybeReopen(params)) {
- return;
- }
-
- if (g_profile_picker_view) {
- g_profile_picker_view->UpdateParams(std::move(params));
- } else {
- if (g_browser_process->IsShuttingDown()) {
- // The profile picker takes a KeepAlive, which is not possible during
- // shutdown.
- return;
- }
- g_profile_picker_view = new ProfilePickerView(std::move(params));
- }
- g_profile_picker_view->Display();
+ return;
}
// static
diff --git a/chrome/browser/ui/views/toolbar/toolbar_view.cc b/chrome/browser/ui/views/toolbar/toolbar_view.cc
index 04636a49d0..cedf440cda 100644
--- a/chrome/browser/ui/views/toolbar/toolbar_view.cc
+++ b/chrome/browser/ui/views/toolbar/toolbar_view.cc
@@ -480,22 +480,22 @@ void ToolbarView::Init() {
avatar_ = container_view_->AddChildView(
std::make_unique<AvatarToolbarButton>(browser_view_));
- bool show_avatar_toolbar_button = true;
+// bool show_avatar_toolbar_button = false;
#if BUILDFLAG(IS_CHROMEOS)
// ChromeOS only badges Incognito, Guest, and captive portal signin icons in
// the browser window.
- show_avatar_toolbar_button =
- browser_->profile()->IsIncognitoProfile() ||
- browser_->profile()->IsGuestSession() ||
- (browser_->profile()->IsOffTheRecord() &&
- browser_->profile()->GetOTRProfileID().IsCaptivePortal());
-#else
- // DevTools profiles are OffTheRecord, so hide it there.
- show_avatar_toolbar_button = browser_->profile()->IsIncognitoProfile() ||
- browser_->profile()->IsGuestSession() ||
- browser_->profile()->IsRegularProfile();
+// show_avatar_toolbar_button =
+// browser_->profile()->IsIncognitoProfile() ||
+// browser_->profile()->IsGuestSession() ||
+// (browser_->profile()->IsOffTheRecord() &&
+// browser_->profile()->GetOTRProfileID().IsCaptivePortal());
+//#else
+// // DevTools profiles are OffTheRecord, so hide it there.
+// show_avatar_toolbar_button = browser_->profile()->IsIncognitoProfile() ||
+// browser_->profile()->IsGuestSession() ||
+// browser_->profile()->IsRegularProfile();
#endif
- avatar_->SetVisible(show_avatar_toolbar_button);
+ avatar_->SetVisible(false);
#if BUILDFLAG(ENABLE_WEBUI_TAB_STRIP)
auto new_tab_button = std::make_unique<ToolbarButton>(base::BindRepeating(
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 0d236c3409..9f3111708f 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -3713,7 +3713,7 @@ const blink::web_pref::WebPreferences WebContentsImpl::ComputeWebPreferences(
if (ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
GetRenderViewHost()->GetProcess()->GetDeprecatedID())) {
prefs.loads_images_automatically = true;
- prefs.javascript_enabled = true;
+ prefs.javascript_enabled = false;
}
prefs.viewport_enabled = command_line.HasSwitch(switches::kEnableViewport);
diff --git a/extensions/browser/extension_webkit_preferences.cc b/extensions/browser/extension_webkit_preferences.cc
index ea362fb212..1feff1636c 100644
--- a/extensions/browser/extension_webkit_preferences.cc
+++ b/extensions/browser/extension_webkit_preferences.cc
@@ -36,7 +36,7 @@ void SetPreferences(const extensions::Extension* extension,
// Extensions are trusted so we override any user preferences for disabling
// javascript or images.
webkit_prefs->loads_images_automatically = true;
- webkit_prefs->javascript_enabled = true;
+ webkit_prefs->javascript_enabled = false;
// Tabs aren't typically allowed to close windows. But extensions shouldn't
// be subject to that.
diff --git a/net/cookies/cookie_monster.cc b/net/cookies/cookie_monster.cc
index fd937f5ec7..d1085f7c9f 100644
--- a/net/cookies/cookie_monster.cc
+++ b/net/cookies/cookie_monster.cc
@@ -529,6 +529,13 @@ void CookieMonster::SetCanonicalCookieAsync(
const CookieOptions& options,
SetCookiesCallback callback,
std::optional<CookieAccessResult> cookie_access_result) {
+
+
+ CookieInclusionStatus status;
+ status.AddExclusionReason(CookieInclusionStatus::ExclusionReason::EXCLUDE_FAILURE_TO_STORE);
+ std::move(callback).Run(CookieAccessResult(status));
+ return;
+
if constexpr (DCHECK_IS_ON()) {
CanonicalCookie::CanonicalizationResult result = cookie->IsCanonical();
DCHECK(result) << result;
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc
index 7e54411c71..883a93c3b8 100644
--- a/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -4148,6 +4148,7 @@ bool LocalFrame::ImagesEnabled() {
}
bool LocalFrame::ScriptEnabled() {
+ return false;
DCHECK(!IsDetached());
// If this is called in the middle of detach, GetDocumentLoader() might
// already be nullptr.Apply the patch:
git apply --check decrapify.patchCompile:
autoninja -C out/Default chromeIt will take a while. Until then have a quick look at the performance of my water cooled 7950x under load:

Open the browser:
out/Default/chromeDevTools will be disabled as that feature is JavaScript based. Enjoy a clean and safe Internet.