Why we forked Firefox and not Chromium

In 2015 Cliqz released its own desktop web browser, forked from Firefox. Up to that point, we had distributed our search and privacy products as a single Firefox addon. In this article we cover why we thought it necessary to create our own browser, why we chose Firefox, and why we think it was the right choice.

Why a browser?

Search is an integral part of the web browsing experience—almost every browsing session starts with a search. All modern browser UIs have search directly integrated into their address bars. Thus, browsers are the primary means of distributing search, something Google realised in the 00’s when they created Chrome to push their search. We realised the same, and therefore wanted to have a browser which we could use to distribute our search, and as a showcase of our vision.

Furthermore, owning the platform is important to keep control over the user experience. This has proved critical in retrospect: At the time our browser extension in Firefox was using the old legacy extension APIs, which gave us significant power to tinker with the browser UI, something we exploited to build our search dropdown. In 2017 these APIs were deprecated, and we could no longer ship this feature to Firefox. Luckily, we had our own browser by this time.

Secondly, distributing a browser gave us the power to control much more of the user experience than an extension could have. Back then the mainstream browsers were paying limited attention to user privacy. From our experience building a web search, we saw the kind of data that was being collected about users and being sold on the “free market” by other actors. We wanted to protect users from this kind of exploitation, and apply privacy-by-design to the browser from the ground up.

At Cliqz we believe browsers are user agents, “a user agent is software (a software agent) that is acting on behalf of a user”[1]. The browser represents a user on the Internet and so is responsible for protecting their privacy. We had already implemented anti-tracking and anti-phishing technologies for our Firefox extension and could integrate them right in our browser.

Why fork a browser?

For these reasons it became clear we wanted to build and distribute our own browser. It was also obvious that there was no need to try to change what existing browsers were already doing well—there would be little value trying to match the already exceptional rendering performance and security of the established browser engines. Instead, we wanted to build features on top. This meant we would have to fork one of the existing engines. Our thinking was to consider the browser as a platform for our features.

This decision would make our life easier in the long run. Browsers are extremely high-velocity projects, and must be kept up-to-date for important security patches. Maintaining a fork in these conditions is challenging, and we have learnt that the only sustainable way to do this is to diverge as little as possible from the upstream project.

We chose to base our work on Firefox as a majority of our code was already a Firefox extension, and to keep as much of our code as possible encapsulated in our extension to make it easier to keep up with Firefox’s upstream changes.

Why not Chromium?

Nowadays it is a de facto standard to use Chromium as a browser base. Numerous companies like Opera, Yandex, Brave, and recently Microsoft decided to go in that direction. From our perspective that choice is not so clear for a variety of reasons:

  • We are much more in line with Mozilla’s raison d’être than with Google’s. We share most of our values with Mozilla, and we consider them allies. When forking a project like this, one is taking the risk that the upstream maintainer kills or modifies features you rely on. We can trust Mozilla much more than Google to not do this.

  • Monopoly-wise, it makes more sense to support Firefox’s code-base. The Blink/Gecko (webrender) market share is not a trivial matter. If all browsers end up using Blink (Google), the Web will suffer as developers will only optimize and test for the Blink rendering engine. The recent loss of the Web’s third independent engine (EdgeHTML), further exacerbates this issue.

But the reasons are also technical:

  • Firefox has open APIs for everything the browser does—a majority of Firefox “application” code is written in JavaScript. Chromium on the other hand does not expose certain areas that are sensitive to Google’s business. The most notable example is the address bar (where Cliqz search lives). Google has no interest in making it easy for others to take control of the address bar; the flow to the default search engine (Google) is protected. Of course one could create new APIs, but that would imply creating them on top of the source-code. This is not a big issue, we have already created a prototype, but then there is the problem of maintaining it.

  • Maintaining any fork is a nightmare because the owners of the projects—mostly Googlers in the case of Chromium—can be aggressive and pervasive in their changes, sometimes to the point of breaking integrations and forcing people to catch-up.

  • It is not “stable”. The introduction of API changes, and support for old APIs, is neither consistent nor coherent. Take for instance Manifest v3, which on the false grounds of security, privacy, and performance will deprecate some of the most powerful and useful APIs that privacy enhancing extensions rely upon, virtually affecting all of them. They backtracked on some of the inital reasons for the changes, but they still intend to push it through, causing havoc on anyone relying on said APIs.

  • Chromium comes with a number of Google services which are not easy to remove. Both Microsoft and Brave invested significant resources just to strip these out. Other APIs, such as screen reader integration, are closed source.

Chromium is a great browser with a fast rendering engine, however it requires significant resources to maintain a fork of it, something we did not have, and were not willing to commit to. The decision to go with Firefox has been vindicated, as it has become even easier over time to integrate our features, while at the same time Chromium is stripping away APIs we consider fundamental to our project.

Cliqz features

Cliqz ships with some home-engineered features which help users to have a safe and private Web experience. Here are some of the most important ones:

  • Cliqz dropdown—is where the Cliqz search lives, right in the address bar. The search results are displayed in the dropdown as the user types, eliminating the need for a search result page and saving time. The results displayed are served from our independent and private search backend.
  • Anti-tracking—implements an algorithmic approach to identify and block trackers as well as fingerprinting attempts, and is continuously updated based on data.
  • Adblocker—allows users to enjoy a fast, ad- and clutter-free Web experience, thanks to an extremely efficient content blocking engine: Read more.
  • Cookie popup blocker—helps the user to cope with forced consent popups on websites, dealing with obscure UX patterns automatically by opting you out from data collection rather then just hiding popups!
  • Auto Forget Window—automatically opens sensitive or explicit links in a new forget window, even if it was initiated from a normal window; users can also blacklist URLs to always open them in a forget window.
  • Antiphishing—prevents users from falling for phishing pages and keep them safe at all times.
  • CliqzTab—is the user dashboard, which shows privacy stats like how many ads were blocked, and how many private data points were removed. It additionally serves curated news and includes few utility widgets like most visited sites and bookmarks.

Firefox is a great platform

We have been shipping our Firefox fork for over four years and have come to realise that Firefox is a great host for forks. Some of its fork-friendly properties are:

  • The browser UI can be themed with CSS, this makes UI and design tweaks very easy for web developers.
  • It is modular and the pref-based architecture makes it quite configurable.
  • It is built on Web technologies. This makes it much easier for developers to get up-to-speed and productive with it. You can also debug the whole browser with devtools.
  • It has first class support for repackaged distributions, making it easy to rebrand the browser[2].
  • It supports extremely powerful extensions, particularly in privileged contexts, which can touch almost all browser internals.
  • It allows for powerful configuration scripts for deep customizations[3].

Universal codebase

We started out with a Firefox Bootstrapped[4] extension using the raw, low-level browser APIs. However, once we started building the browser we wanted to also ship features to our mobile browsers on Android and iOS. Later, we wanted to run this code on top of the new webextension APIs that came in Firefox 57. With a small team it would be a challenge to keep the business logic consistent across environments and codebases.

To handle this we made the architectural decision of running JavaScript everywhere. The business logic would be written in isomorphic/universal JavaScript and then we would add platform-specific implementations underneath to handle the specifics of each runtime. Our browser-core monorepo contains code for products across all platforms:

  • Webextensions, compatible with Chrome, Firefox, and Edge.
  • Android and iOS using React-native.
  • NodeJS, for testing and headless mode.

To give an example, we have a search module that provides results for a given query (using RxJS as described in our previous post). This is implemented as a module in browser-core. As we mentioned previously, one source for results is the browser’s history. This is platform-specific, so we have different history databases on desktop and mobile. At build time, the appropriate JavaScript implementation is bundled, so the search module can query the platform’s database. The search UIs are also different: on desktop results are rendered in an iframe below the URL bar, while on mobile the UI is implemented with React-Native. In both cases they push queries to, and get results from the same search implementation.

Android

The situation on Android is a little different than on desktop. The OS is controlled by Google, and the majority of the users end up using either the built-in browser or Chrome (shipped with the Android distribution). Fortunately, users still have a choice. You can change your default browser and the OS will respect that choice whenever you click a link. We have built multiple Android browsers, with different approaches each time:

Cliqz for Android—Like many Android browsers, Cliqz for Android is a stock Android WebView based application. What is uncommon about it is the fact that it runs our shared JavaScript codebase in a React-Native runtime. Our privacy protection features like the adblocker and anti-tracking run in the React-Native thread and are still able to intercept network requests that are happening in the system WebView. This unique approach allowed us to provide those features without having to fork the complete browser engine.

Ghostery for Android—After Ghostery joined Cliqz, we decided to upgrade the Ghostery Android Browser. The goal was to provide the full Ghostery experience on mobile phones and to do so we decided to build a new version on top of Firefox for Android (aka Fennec). The move allowed us to fully utilize the potential of WebExtension that Firefox for Android provides. This was basically mimicking our desktop approach.

Fennec is an impressive feat of engineering, that basically is a real Firefox, but on mobile. It has the Gecko rendering engine and SpiderMonkey JavaScript engine. It’s a real deal. And on top, it has a native Android UI for the familiar look and feel.

Unfortunately Fennec development is a very complicated process. Developers constantly have to jump between different layers and technologies to implement new features or fix bugs. Not many developers are able to effecively jump between C++, JavaScript, and Java.

The limitation of Fennec’s architecture are well understood by Mozillians and in 2019 Fennec was retired.

Next Gen of Cliqz Browser—Based on the lessons from Fennec, Mozillians have created a completely new architecture to create Android browser. It is, at the core, a GeckoView; a nicely encapsulated browser engine with very well crafted Java APIs. With GeckoView, any developer can create a Gecko-backed browser without having to ever touch JavaScript or C++. GeckoView is just “a library” similar to WebView being shipped with Android.

But GeckoView is able to run WebExtensions and thanks to that it is a perfect fit for the Cliqz cause. On top of GeckoView, we can build beautiful browser UIs and ship our shared JavaScript codebase in the form of WebExtensions. So that with our blazing fast adblocker we can finally compete with Chromium in terms of speed and exceed it in every aspect of privacy protection.

iOS

Apple’s iOS platform is also very different. Users cannot choose a default browser and browser vendors cannot ship their own rendering or JavaScript engines. All developers have to use stock iOS WebView (WKWebView). This limitation is imposed on all browser vendors: Mozilla’s and even Google’s browsers are “just” iOS applications.

The Cliqz browser is no different when it comes to the basics. We have forked Firefox for iOS to get a stable base to create our user agent. Why Firefox? It is an open source and really solid, battle tested project. But it is not the only option: DuckDuckGo would have been a good choice too.

As the iOS WebView does not come with the capability to run extensions, we had to invent one ourself. Again, React Native came as a solution: We have created a hybrid/brownfield application that ships the browser-core running in React Native in our heavily modified Firefox codebase.

It might be important to mention that we have forked Firefox for iOS three times already. Trying out different strategies for running a fork:

  1. Soft fork with rare syncs with upstream—it proved to be complicated to maintain our substantial changes mostly around the WebView. We chose to modify Firefox code to use the older but more powerful UIWebView in order to provide privacy features.
  2. Soft fork with regular syncs—was a failure as it limited our capability to shape the browser to our liking.
  3. Hard fork with cherry-picks (current generation)—so far developers’ favorite as it gives the freedom to make changes without having to worry about conflicts with upstream.

Note that Firefox for iOS is not a very high velocity project. This means that manual cherry-picking for security fixes is still feasible.

More than a browser

With an embedded search engine, anti-tracking and adblocker, Cliqz leads the new wave of browsers that take privacy seriously. The browser wars are real and are about to change the Internet again…

Footnotes:


  1. User agent on Wikipedia link. ↩︎

  2. https://firefox-source-docs.mozilla.org/taskcluster/partner-repacks.html. ↩︎

  3. https://support.mozilla.org/en-US/kb/customizing-firefox-using-autoconfig. ↩︎

  4. https://developer.mozilla.org/en-US/docs/Archive/Add-ons/Bootstrapped_extensions. ↩︎