Coffee Space


Serenity OS Ladybird

Preview Image


Recently on Hacker News I wrote about a project I’ve been thinking about for quite some time:

The real problem is that nearly all website render terribly. It just can’t keep up with the complexity that it the modern web. It’s a real shame.

I was thinking since quite a while now to write a wrapper around the Serenity OS browser [1] that supports JS, CSS and WASM, and passes ACID 3 tests [2].

I did have a quick look at the source, but couldn’t think of a nice way to wrap it as it’s quite closely tied to the Serenity OS GUI.



Once I first saw it I quite liked the idea that there was this relatively complete competitive browser ready to rock and roll. It is insanely cool how fast this thing came together on a bespoke platform.

Macuyiko replied with:

You’re in luck, Andreas has been hacking on that since a couple of months. They’re calling the Linux version of the browser Ladybird:

Wait, what?! I have to investigate this.


After installing the recommended packages (I run X11 Ubuntu so don’t need the Wayland stuff):

0001 $ sudo apt install build-essential cmake libgl1-mesa-dev ninja-build \
0002                    qt6-base-dev qt6-tools-dev-tools

I created somewhere I could experiment:

0003 $ mkdir browser
0004 $ cd browser
0005 $ git init
0006 $ git submodule add
0007 $ git submodule add

(Note the use of the HTTPS remote URLs.)

I don’t really know much about this Ninja build process. So I then wrote a bash script named that handles the entire build process, including pulling the latest code (which is somewhat dangerous):

0008 ROOT="$(pwd)"
0010 # Time variables
0011 time_beg=0
0012 time_end=0
0013 time_run=0
0015 # time_start()
0016 #
0017 # Begin timing.
0018 function time_start {
0019   time_beg=$(date +%s.%N)
0020   time_end=$time_beg
0021   time_run=0
0022 }
0024 # time_stop()
0025 #
0026 # End timing.
0027 function time_stop {
0028   time_end=$(date +%s.%N)
0029   time_run=$(echo "$time_end - $time_beg" | bc -l)
0030   echo "$time_run"
0031 }
0033 # begin()
0034 #
0035 # Log the fact we are beginning some process.
0036 #
0037 # @param $1 The message to be logged.
0038 function begin {
0039   time_start
0040   echo "[>>] $1"
0041 }
0043 # end()
0044 #
0045 # Log the fact we are ending some process.
0046 #
0047 # @param $1 The message to be logged.
0048 function end {
0049   diff="$(time_stop)"
0050   echo "[<<] $1 - Took: $diff seconds"
0051 }
0053 # log()
0054 #
0055 # Log a generic message.
0056 #
0057 # @param $1 The message to be logged.
0058 function log {
0059   echo "[--] $1"
0060 }
0062 # main()
0063 #
0064 # Run the main script.
0065 #
0066 # @param $@ The command line arguments.
0067 function main {
0068   begin "Pull latest Ladybird"
0069   cd ladybird
0070     git fetch
0071     git pull
0072   cd "$ROOT"
0073   end "Pulled latest Ladybird"
0075   begin "Pull latest Serenity"
0076   cd serenity
0077     git fetch
0078     git pull
0079   cd "$ROOT"
0080   end "Pulled latest Serenity"
0082   # Remove the previous build files
0083   begin "Remove Ladybird build files"
0084   cd ladybird
0085     rm -rf Build
0086   cd "$ROOT"
0087   end "Removed Ladybird build files"
0089   # Build the project
0090   begin "Build the browser"
0091   cd ladybird
0092     cmake -GNinja -B Build -DSERENITY_SOURCE_DIR=../serenity
0093     cmake --build Build
0094     ninja -C Build run
0095   cd "$ROOT"
0096   end "Built the browser"
0097 }
0099 main $@

Now to pull the latest changed and build the latest code, I simply run:

0100 $ bash

After some building time (tea or coffee could be made at this point)…


Without further delay, here is a screenshot of what you should see:

Serenity OS browser

NOTE: This was performed on the master branch at the time of testing - which is assumed to be stable.

Initial impression is that the interface is clean, minimalist, fast looking.

The next test was a stress test against the most heavy website I could imagine:

CoffeeSpace website

The CSS appears to at least be compliant with the basics. Not bad at all. With this you could easily view well written static websites with ease.

Yes, it can view it’s own source on GitHub:

Serenity OS GitHub

And yes, you can login to GitHub too:

GitHub login

Can we search via DuckDuckGo?

DuckDuckGo fail

Annoyingly, Google works fine though:

Google search

So one of the things that interested me was the ACID3 test, which even the latest and greatest browsers cannot pass:


Unfortunately it failed this test. It does reasonably well though. I would like to look at what it failed on - but unfortunately it actually stops processing, so I cannot tell which tests it fails or passes.

Note to developers: I would suggest adding this to your regression tests, no point in losing existing functionality!

I performed the following SunSpider 1.0.2 tests, a JavaScript browser stress test by wekit. For the Serenity OS browser:

Ladybird SunSpider

Of course this doesn’t mean too much, until you look at the same tests on the same system, this time running in Firefox:

Firefox SunSpider


On JetStream2, Ladybird simply refuses to run entirely.

As for Youtube:

Youtube infinite loop

Yeah, so Youtube causes the browser to sit in an infinite loop using 100% CPU. Nice. Who needs Google anyway?

Interestingly I can always cause the browser to reliably ‘stop’ by pressing the thumb back button on my mouse (which usually goes back a page in other browsers).

Final Notes

Firstly, I am really quite impressed. This is an insane undertaking, and all those involved have done a heroic effort. Seriously, please keep going. I thought we would be forever confined to the likes of Dillo or NetSurf if we wanted to dream about a lean browser with CSS, even thinking about JS. We desperately need more competition in this space.

That said, it’s not quite ready for prime time, but shows a lot of potential. In a year or less I could see this being an experimental daily driver. I wouldn’t be surprised if some developers are already daily driving the browser, but for me with hundreds of tabs open, it doesn’t yet seem possible.

Where this browser could potentially be really cool is compiled extensions. Imagine for example how fast and effective something like uBlock would be with a compiled extension, rather than running in JavaScript. I imagine some other issues like memory or CPU could also be solved this way.

Another way this browser could be cool is a baked-in browser for an application to compile with (if you’re going to do it, it may as well be a lean browser). The binary appears to weigh in at just 8.1MB, which is more than reasonable to be packaged inside another binary.