Intro
I don’t know exactly when. But, I have a dream to shift my career from a web developer into web browser engineer. I wish I could make it happen in a distant future. At the time this post is published, there are popular browser engines in this world:
- WebKit for Safari
- Chromium (Blink) for Google Chrome
- Gecko for Firefox
- Servo
- LibWeb for Ladybird
The Ladybird is a new browser engine from scratch by Andreas Kling (he was ex-Apple who works for WebKit - as far as I follow him on Twitter and I watch him on YouTube). In a video, Andreas mentioned that he and the team have a plan to move the Ladybird code from C/C++ into Swift. I’m excited and waiting that day happen. But, it’s not happened. Instead, Andreas and the team decide to move it into Rust with help from AI - because the C/C++ interopability on Swift doesn’t match the expectation criteria for them. Honestly, I’m sad because I’m really wanna see the browser engine build with Swift from scratch - mix with C/C++ interopability - oh, hi Skia and Harfbuzz.
Rather than waiting and waiting to see that day happen, why don’t I made a try to make a browser engine with Swift from scratch?
No one is perfect, but making progress moves you closer to it.
A Plan
- It doesn’t have to be perfect or using fancy things like C/C++ interopability that can integrate with Skia or Harfbuzz or even use it widely.
- The browser engine can read URL, parse the content from URL with HTML parser, CSS parser, and JavaScript Engine then show it in a page in a tab. That’s it for a good start.
But, I need a solid and robust resource to teach me how to make a web browser.
No no no. Please don’t suggest me the WHATWG HTML Standard. It’s too too too big. 😵💫
Luckily I found it! The Browser Engineering book - created by Pavel Panchekha and Chris Harrelson. This books covers the foundation of how to make the web browser using Python. I have follow the chapter since October 2025. I save it into a GitHub repository called brownie. Now, I’m in the last chapter and soon it will be finished. :)
Reasons
There are three reasons why I choose Swift as programming language to make a browser engine:
- Curiosity
The real-world browser engines mostly build with C/C++. Recently, Rust joined this competition followed by Zig. Meanwhile, Swift is a programming language that has integration with desktop or mobile platform. Mostly, the browser engines will be wrapped into a desktop or mobile app then Swift has fulfill this criteria. I don’t need to waste my time to seeking the GUI desktop engine. :)
In the end I would like to know how far Swift can be used as programming language to build a browser engine.
- Everything is object
Everything is object. The web has Document Object Model (DOM). Swift has Object Oriented Programming. That’s it! I don’t want to explain it more detail. Ask Claude!
How does the DOM relate to Swift’s OOP model in the context of building a browser engine?
- Learning
I’m a beginner in building browser engine area. Mostly, I’m just a consumer who use the browser. Now, it’s time to learn how to build it.
AI is My Assistant
Artificial Intelligence has turned into Large Language Model (LLM) that turned into a product called Claude (one of them). The code program is no longer mystery. The another mystery is the meaning of the code program and it’s impact to the sofware. As programmer you still need to learn programming language in the AI era. You still have the job to write and review the code to bring high quality software!
Let’s start for the execution. At the first try, I just throw all the things from the brownie and tell the Claude to port it into Swift. Errrr… It doesn’t work as expected. Then, I change my workflow.
First, I split the parts of brownie into three parts (branches):
- Part 1 - branch
ch01-10: It covers chapter 1 (Downloading Web Pages) to 10 (Keeping Data Private) - Part 2 - branch
ch11-14: It covers chapter 11 (Adding Visual Effects) to 14 (Making Content Accessible) - Part 3 - branch
ch15-16: It covers chapter 15 (Supporting Embedded Content) to 16 (Reusing Previous Computation)
Second, I create a Swift project for web browser engine. I called it ToyStack.
# Swift convention name for project name is PascalCase
mkdir ToyStack
cd ToyStack
# By default swift will create package for type Library.
# But I set the type to be Executable because I execute a program to run a browser
# So, you will get Sources directory, .gitignore file, and Package.swift
swift package init --type=executable --name ToyStack
Inside the ToyStack I put the brownie project and switch into ch01-10 branch. Then, I start chat with Claude with the prompt like this.
I want to make a browser engine with Swift programming language. Currently, I have brownie - a browser engine with Python that comes from Browser Engineering book. Your task is read the Python code inside the brownie and porting it into Swift. Create a plan with step by step which one is first, second, and so on. In the end, you’re a guider and give me the code BUT you’re NOT ALLOWED to edit the code. I’m a learner and will re-type the code program to get better understanding of the meaning of code.
Now, the ToyStack has covered the chapter 14 along with some exercise that comes from the Browser Engineering. The ToyStack doesn’t have any third-party dependencies. It’s only using Swift and SwiftUI. The rendering engine is built from scratch by follow the Browser Engineering book. Meanwhile for JavaScript engine, I use JavaScriptCore (Safari) instead of build from scratch. Maybe I will try to built it using Swift too in the future.
Closing
Thanks to the help from AI, the code is no longer mystery and build a “toy” browser engine can be done in days instead of weeks or months. But, for the real-world browser engine is another story. My experience when make the browser engine with Swift is mixed feeling. Mostly, I’m confused with the output of code program because I have less experience with Swift programming language. Even along with the web browser term like Chrome - it’s a control for managing tabs, back and forward button, address bar input, bookmark site. I was thinking the Chrome is just the product name of Google Chrome. 🙈
If I want to make a description on how the browser engine works maybe like this:
- Everything starts from URL
- The URL contains information: HTML tags along with CSS (
<style>or) and JavaScript ( - Then, you have two parser and one engine: HTML parser, CSS parser, and JavaScript engine. Those are used for parsing the tags into the DocumentLayout.
- From DocumentLayout to BlockLayout. From BlockLayout into LineLayout, InputLayout, and ButtonLayout or even ImageLayout.
- The layout result is inside a tab.
- Each tab are managed by a Chrome.
- Then, close the tab and browser window. Get out and enjoy the real-life. :)
The ToyStack doesn’t finished yet. There are things that is still on going - add features and optimized. Maybe I wanna play a game inside the ToyStack one day. ;)
GitHub repository: kresnasatya/ToyStack.