faceicon

In this entry, I will explain how you can build your own custom browser using Chromium project. My goal is not to create a browser from scratch; If that's what you want to do, you should check SerenityOS project (link). The purpose of this research was to learn more about how current browsers (e.g., Brave, Opera, Chrome, Edge) are constructed using the Chromium project as a base.

What’s Chromium

According to their website, “Chromium is an open-source browser project that aims to build a safer, faster, and more stable way for all Internet users to experience the web”. Most of the popular browsers people use daily (Google Chrome, Brave, Edge, Opera…) are based on this project.

If you are wondering why I said Google Chrome is based on Chromium, YES Chromium is not the same as Chrome. Take a look (link).

Chromium project also includes other open-source projects (OSS) like the following ones:

  • ChromiumOS: Root repo of many for the Linux and web-based OS
  • V8: JavaScript and WASM runtime. (NodeJS uses this)
  • Skia: Low level graphics
  • Angle: 3D graphics
  • Devtools-frontend: Browser developer tools UI
  • WebRTC: Real time audio/video library used by many browsers.

For a complete list could be found at the link. Some of them are used as dependencies in the Chromium browser.

Source code

The important folders we should be aware of are (link):

  • chrome: Application layer of Google Chrome.
  • content: Multi-process sandboxed implementation of the web platform (link).
  • third_party/blink/: The web engine responsible for turning HTML, CSS and scripts into paint commands and other state changes. Web engine forked from WebKit.

Some years ago they separated chrome and content folder in order to have a modularized code. This structure allows to be easier to reutilize the code in other projects.

How to search on the code

Before we download the code, let me explain how to navigate this large codebase. Chromium provides a website where we can search for specific parts of the code. Depending on your goal, this task of finding and understanding the code could be really complex. Chromium website provides code paths for common operations (link). Let’s try a dumb example in which we want to change the menu that appears when we do right click in the webpage.

right-click-menu

For this task, I will use the search website I mentioned earlier. In this case, I will search for the text “Send to your devices” because it will be easier.

search

As we might expect, they use i18n (internalization) for providing multi-language support. So, let’s search using the id “IDS_CONTEXT_MENU_SEND_TAB_TO_SELF”.

search

After searching through the Context Menu code, I finally found the code that is responsible for rendering the menu:

search

Build our custom browser

Download and build

In this section I will download and build the project. For this task, it as simple as follow the following wiki. Compiling time may vary depending on your setup but it can take a couple of hours or even longer. In the meantime, you could read other articles of this website tackling other topics ;)

Modifications

Once we make the changes, the build of the binary will be faster because it will only recompile the changes. If you want to learn how to make some stupid changes to the source code, take a look the following resources:

  • Video tutorial: The first resource is a video tutorial that shows you how to change the name and logo of the browser.
  • Beginners guide to contribute article : The second resource is a tutorial that shows you how to add a new button to the avatar menu and contribute to the project.

websecbrowser

Brave Example

In the second part of this entry, we will explain how Brave is built on top of Chromium project. Brave provides some wikis on their github project explaining how it works more in depth (Brave Patching) or the deviations from Chromium. In this section I just provide a few examples of this patching process.

Brave Startup Patching

Brave adds command line switches before launching the browser as Chromium does. This patch includes code of Chromium allowing to call the original function after a few command line modifications.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// File: brave-core/chromium_src/chrome/app/chrome_main_delegate.cc
// ...

#define BasicStartupComplete BasicStartupComplete_ChromiumImpl
#include "src/chrome/app/chrome_main_delegate.cc"
#undef BasicStartupComplete

// ...


absl::optional<int> ChromeMainDelegate::BasicStartupComplete() {
// After some command line switches
// ...

// The code returns to the original code of Chromium
return ChromeMainDelegate::BasicStartupComplete_ChromiumImpl();
}

Pinned CA certificates

On deviations they claimed that they have replaced the list of hostnames with pinned CA certificates with a Brave-specific one. In this case, they used a similar approach. When the function is called, they just change the arguments to Brave ones.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// File: brave-core/chromium_src/net/tools/transport_security_state_generator/input_file_parsers.cc
// ...

#define ParseJSON ParseJSON_ChromiumImpl
#define ParseCertificatesFile ParseCertificatesFile_ChromiumImpl
#include "src/net/tools/transport_security_state_generator/input_file_parsers.cc"
#undef ParseCertificatesFile
#undef ParseJSON

// ...

bool ParseCertificatesFile(base::StringPiece certs_input,
Pinsets* pinsets,
base::Time* timestamp) {

base::StringPiece brave_certs = R"(RAW CERTIFICATES)"

return ParseCertificatesFile_ChromiumImpl(brave_certs, pinsets, timestamp);
}

//...


bool ParseJSON(base::StringPiece json,
TransportSecurityStateEntries* entries,
Pinsets* pinsets) {
// Other stuff..
base::StringPiece brave_json = R"(RAW JSON)"

return ParseJSON_ChromiumImpl(brave_json, entries, pinsets);
}

Final words

If you want to learn more, just be brave (ba dum tsss!) and take a look the real code of both projects. You could start searching for a specific behavior or checking the examples provided by developers. Also, I recommend you to start reading some of the design documents.

If you have any recommendation/mistake/feedback, feel free to reach me twitter :)

References: