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.
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.
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.
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”.
After searching through the Context Menu code, I finally found the code that is responsible for rendering the menu:
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.
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 | // File: brave-core/chromium_src/chrome/app/chrome_main_delegate.cc |
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 | // File: brave-core/chromium_src/net/tools/transport_security_state_generator/input_file_parsers.cc |
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:
- Chromium project website
- Recommended: Chromium Overview Video
- Recommended: Chrome Comic Book