# Ladybird Browser — User Guide

## 1. Quick Start

Ladybird is an independent, from-scratch web browser built entirely outside the Chromium and Gecko ecosystems. It implements its own HTML/CSS rendering engine, JavaScript engine, and networking stack — all written primarily in C++ with select Rust components. The project originated from SerenityOS and is licensed under BSD-2-Clause.

**Key features:**

- Standards-compliant HTML, CSS, and JavaScript rendering
- Multi-process architecture for stability and security (each tab runs in its own process)
- Native UI on macOS (AppKit), Linux/FreeBSD (Qt 6 or GTK 4), Windows (Qt 6), and Android (experimental)
- Built-in DNS-over-TLS with optional DNSSEC validation
- Configurable search engines with autocomplete
- Per-site permissions management
- Global Privacy Control (GPC) support
- Hardware-accelerated rendering via Skia with Vulkan (Linux/Windows/FreeBSD) or Metal (macOS)
- WebDriver support for automated testing

**Prerequisites:** A C++23-capable compiler (Clang 18+ or GCC 14+), CMake 3.30+, Rust 1.95+, Python 3, and `vcpkg` for dependency management.

**Quickest path to a running browser (Linux):**

```bash
git clone https://github.com/LadybirdBrowser/ladybird.git
cd ladybird
python3 Meta/ladybird.py build
python3 Meta/ladybird.py run
```

> [!TIP]
> On macOS, `Meta/ladybird.py run` launches `Ladybird.app` directly. On Linux and FreeBSD, it launches the `Ladybird` binary from the build output directory.

---

## 2. Installation

Ladybird is currently distributed as source code only — there are no pre-built binary packages. You build it from the Git repository.

### System Requirements

| Requirement | Minimum |
|---|---|
| **CPU** | x86_64 or AArch64 |
| **RAM** | 8 GB recommended (16 GB for parallel builds) |
| **Disk** | ~10 GB (source + build + vcpkg cache) |
| **OS** | Linux (glibc), macOS 13+, Windows 10+, FreeBSD 14+ |
| **C++ Compiler** | Clang 18+ or GCC 14+ (C++23 required) |
| **CMake** | 3.30.0+ |
| **Rust** | 1.95.0 (channel pinned in `rust-toolchain.toml`) |
| **Python** | 3.8+ |
| **Ninja** | Recommended build backend |

### Platform-Specific Dependencies

=== "Linux (Debian/Ubuntu)"
    ```bash
    sudo apt install build-essential cmake ninja-build curl git \
        pkg-config libvulkan-dev libfontconfig-dev libfreetype-dev \
        libharfbuzz-dev autoconf automake libtool nasm
    ```

=== "Linux (Fedora)"
    ```bash
    sudo dnf install gcc-c++ cmake ninja-build curl git \
        pkg-config vulkan-devel fontconfig-devel freetype-devel \
        harfbuzz-devel autoconf automake libtool nasm
    ```

=== "macOS"
    ```bash
    xcode-select --install
    brew install cmake ninja autoconf automake libtool nasm
    ```

=== "Windows"
    ```text
    Install Visual Studio 2022 with "Desktop development with C++" workload.
    Install CMake, Ninja, Python 3, and Rust from their official installers.
    ```

=== "FreeBSD"
    ```bash
    pkg install cmake ninja curl git pkgconf vulkan-headers \
        fontconfig freetype2 harfbuzz autoconf automake libtool nasm
    ```

> [!IMPORTANT]
> Rust 1.95.0 is pinned via `rust-toolchain.toml` in the repository root. If you use `rustup`, it will automatically download and use the correct version when you build inside the repo directory.

### Build Steps

1. **Clone the repository:**

   ```bash
   git clone https://github.com/LadybirdBrowser/ladybird.git
   cd ladybird
   ```

2. **Build with the default Release preset:**

   ```bash
   python3 Meta/ladybird.py build
   ```

   This invokes CMake with the `Release` preset, fetches all vcpkg dependencies automatically, compiles the browser and all services, and produces the output binary.

3. **Run the browser:**

   ```bash
   python3 Meta/ladybird.py run
   ```

> [!TIP]
> Pass `--preset Debug` to `Meta/ladybird.py build` for a debug build with symbols. Use `--preset Sanitizer` to build with AddressSanitizer and UndefinedBehaviorSanitizer (Linux/macOS only).

### Build Options

The `Meta/ladybird.py` build script accepts several options:

| Option | Description |
|---|---|
| `--preset <name>` | CMake build preset: `Release` (default), `Debug`, `Sanitizer` |
| `--cc <compiler>` | Override the C compiler |
| `--cxx <compiler>` | Override the C++ compiler |
| `--jobs / -j <N>` | Number of parallel build jobs (defaults to `$MAKEJOBS` or CPU count) |
| `--gui <backend>` | UI toolkit: `qt` (default on Linux/Windows/FreeBSD), `gtk` (Linux), or AppKit (auto-selected on macOS) |

**Build-specific targets:**

```bash
# Build only the WebDriver binary
python3 Meta/ladybird.py build WebDriver

# Build the web test runner
python3 Meta/ladybird.py build test-web
```

### Build Output Locations

| Platform | Binary location |
|---|---|
| **macOS** | `Build/Release/bin/Ladybird.app/Contents/MacOS/Ladybird` |
| **Linux / FreeBSD / Windows** | `Build/Release/bin/Ladybird` |

### Choosing a UI Backend

Ladybird supports three native UI toolkits:

| Backend | Platforms | Notes |
|---|---|---|
| **Qt 6** | Linux, Windows, FreeBSD, macOS | Default on non-macOS. Full feature parity. |
| **GTK 4** | Linux | Uses libadwaita for GNOME integration. Build with `--gui gtk`. D-Bus activation supported. |
| **AppKit** | macOS | Default and recommended on macOS. Native Cocoa interface. |

> [!NOTE]
> The GTK backend is newer and some features like the bookmarks bar are still being implemented.

### Post-Install Verification

After building, verify the installation:

```bash
python3 Meta/ladybird.py run -- --headless screenshot https://example.com
```

```text
# Saves a screenshot of example.com and exits
```

### Install Troubleshooting

**CMake version too old:**
Update CMake to 3.30.0+. On Ubuntu, use the Kitware APT repository for the latest version.

**vcpkg download failures:**
Ensure you have a working internet connection and `curl` installed. If behind a proxy, set `HTTPS_PROXY` and `HTTP_PROXY` environment variables.

**Rust toolchain not found:**
Install `rustup` from https://rustup.rs/ and run a build inside the repo. The `rust-toolchain.toml` ensures the correct version is used.

**Missing Vulkan headers (Linux):**
Install your distribution's Vulkan development package (`libvulkan-dev` on Debian/Ubuntu, `vulkan-devel` on Fedora).

**Build fails with memory errors:**
Reduce parallel jobs: `python3 Meta/ladybird.py build -j 4`. Large builds can consume significant RAM.

**Qt 6 not found:**
vcpkg builds Qt 6 automatically. If you want to use a system Qt, ensure Qt 6.7+ is installed and discoverable by CMake.

**macOS: Xcode command-line tools missing:**
Run `xcode-select --install` and accept the license agreement.

**Windows: Compiler not found:**
Ensure you run the build from a "Developer Command Prompt for VS 2022" or have the MSVC toolchain in your PATH.

**Pre-commit hooks failing:**
Install pre-commit (`pip install pre-commit`) and run `pre-commit install` in the repo root.

---

## 3. Configuration

Ladybird is configured through two mechanisms: the graphical settings page (`about:settings`) and command-line flags.

### Browser Settings (about:settings)

Navigate to `about:settings` in the address bar to access the graphical configuration interface. Settings are organized into the following categories:

#### Search

Configure the default search engine and autocomplete provider. Ladybird includes several built-in search engines and supports custom engines with URL templates.

- **Default search engine** — used when typing queries in the address bar
- **Autocomplete engine** — provides suggestions as you type
- **Custom search engines** — add your own with a name and URL template (use `%s` as the query placeholder)

#### Default Zoom Level

Set the default page zoom from 33% to 500%. Available presets: 33%, 50%, 67%, 75%, 80%, 90%, 100%, 110%, 125%, 150%, 175%, 200%, 250%, 300%, 400%, 500%.

#### Languages

Configure preferred languages for web content. Drag to reorder priority. Over 120 language codes are supported, displayed using `Intl.DisplayNames` for readability.

#### Network / DNS

| Setting | Description | Default |
|---|---|---|
| **Upstream DNS** | `System` (OS resolver) or `Custom` | System |
| **DNS type** | `UDP` or `TLS` (DNS-over-TLS) | UDP |
| **Server address** | IP address of custom DNS server | — |
| **Port** | DNS server port | 53 (UDP) / 853 (TLS) |
| **DNSSEC** | Validate DNSSEC locally | Off |

> [!WARNING]
> When using custom DNS-over-TLS, ensure your DNS server supports TLS on the configured port. Misconfiguration will cause all DNS resolution to fail, making the browser unable to load any pages.

#### Privacy

- **Disk cache** — configure maximum cache size (in MiB or GiB)
- **Global Privacy Control (GPC)** — sends the `Sec-GPC: 1` header to websites indicating a do-not-sell/share preference
- **Clear browsing data** — selectively clear cached files, browsing history, and/or site data. Time range options: last hour, last 4 hours, today, or all time

#### New Tab Page

Set a custom URL for new tabs. Defaults to `about:newtab`. Enter any valid URL and it will load when you open a new tab.

#### Permissions

Manage per-site permissions with a global toggle and per-site filter list. Currently supports autoplay settings — control whether sites can automatically play media.

#### Browsing Behavior

Toggle autoscroll functionality (middle-click scrolling).

### Command-Line Flags

Ladybird accepts command-line flags for advanced configuration. Pass them after `--` when using the build script, or directly when running the binary:

```bash
# Via build script
python3 Meta/ladybird.py run -- --flag1 --flag2 https://example.com

# Direct binary
./Build/Release/bin/Ladybird --flag1 --flag2 https://example.com
```

**Commonly used flags:**

| Flag | Description |
|---|---|
| `--new-window` / `-n` | Force opening URLs in a new window |
| `--allow-popups` | Disable popup blocking |
| `--disable-scripting` | Disable JavaScript entirely |
| `--enable-autoplay` | Enable multimedia autoplay globally |
| `--force-cpu-painting` | Use CPU rendering instead of GPU (Skia CPU backend) |
| `--user-agent-preset <name>` | Use a named User-Agent string preset |
| `--dns-server <host>` | Custom DNS server address |
| `--dns-port <port>` | DNS server port (default: 53, or 853 with `--dot`) |
| `--dot` | Enable DNS over TLS |
| `--dnssec` | Enable local DNSSEC validation |
| `--default-time-zone <tz>` | Override the default time zone |

See the Admin Guide for the complete flag reference including developer and debug flags.

---

## 4. Core Usage

### Browsing the Web

Launch Ladybird and type a URL or search query in the address bar. The browser supports standard navigation:

- **Address bar** — type a URL to navigate directly, or type a search query to search using your configured engine
- **Back / Forward** — navigate through your browsing history
- **Reload** — refresh the current page
- **Tabs** — open multiple pages in tabs within a single window
- **New window** — open additional browser windows

### Tab Management

| Action | How |
|---|---|
| Open new tab | Click the `+` button or use the keyboard shortcut |
| Close tab | Click the `×` on the tab, or use the keyboard shortcut |
| Switch tabs | Click the tab header |
| Open link in new tab | Right-click a link and select the option from the context menu |

### Bookmarks

Ladybird includes a bookmark system with folder organization:

- **Add bookmark** — bookmark the current page via the browser menu
- **Bookmark folders** — organize bookmarks into hierarchical folders
- **Bookmarks bar** — quick-access bar below the address bar (Qt and AppKit backends)
- **Edit / Delete** — right-click bookmarks for context menu options

> [!NOTE]
> The GTK backend's bookmark bar implementation is still in progress. Bookmarks are stored but not yet displayed in the toolbar.

### Search

The address bar doubles as a search bar. When you type text that is not a valid URL, Ladybird searches using your configured search engine. Autocomplete suggestions appear as you type.

To manage search engines, visit `about:settings` and navigate to the Search section. You can:

- Select from built-in engines
- Add custom engines with a URL template
- Choose a separate autocomplete provider

### Zoom

Adjust the page zoom level:

- **Default zoom** — set globally in `about:settings` → Default Zoom Level
- **Per-page zoom** — use keyboard shortcuts or the View menu to zoom in/out on the current page
- **Range** — 33% to 500%

### Downloads

When a download starts, Ladybird prompts you to choose a save location. The browser displays a confirmation notification when the download begins.

### Developer Tools

Ladybird includes a Firefox DevTools protocol-compatible inspector. Enable it with:

```bash
Ladybird --devtools
```

This starts a DevTools server on the default port. Connect from Firefox DevTools or any compatible client to inspect pages, view the DOM tree, examine CSS, and debug JavaScript.

> [!TIP]
> Pass a specific port number: `--devtools 9222` to avoid conflicts with other DevTools instances.

### Headless Mode

Run Ladybird without a visible window for automation and testing:

```bash
# Take a screenshot of a webpage
Ladybird --headless screenshot https://example.com

# Dump the layout tree
Ladybird --headless layout-tree https://example.com

# Dump rendered text content
Ladybird --headless text https://example.com

# Manual mode (waits for programmatic control)
Ladybird --headless manual
```

| Mode | Output |
|---|---|
| `screenshot` | Saves a PNG screenshot of the rendered page |
| `layout-tree` | Prints the internal layout tree structure |
| `text` | Prints the visible text content |
| `manual` | Starts headless and waits for external control |

Headless mode options:

| Flag | Default | Description |
|---|---|---|
| `--window-width` | 800 | Viewport width in pixels |
| `--window-height` | 600 | Viewport height in pixels |
| `--screenshot-delay` | 0 | Seconds to wait before capturing |

### Internal Pages

Ladybird provides several `about:` pages:

| Page | Purpose |
|---|---|
| `about:settings` | Browser configuration |
| `about:newtab` | Default new tab page |

---

## 5. Common Tasks

### Task 1: Configure DNS-over-TLS with DNSSEC

**Goal:** Route all DNS queries through an encrypted TLS connection with DNSSEC validation.

1. Open `about:settings` and go to the Network section
2. Change "Upstream DNS" from "System" to "Custom"
3. Set DNS type to "TLS"
4. Enter your DNS server address (e.g., `1.1.1.1` for Cloudflare or `8.8.8.8` for Google)
5. Port will default to 853 for TLS
6. Enable the DNSSEC toggle

**Verify:** Navigate to any website — if DNS resolution works, the page loads. If not, check the server address and ensure your network allows outbound connections on port 853.

**Alternative (CLI):**

```bash
Ladybird --dot --dns-server 1.1.1.1 --dns-port 853 --dnssec
```

> [!WARNING]
> CLI-specified DNS settings override the graphical settings and cannot be changed from `about:settings` during that session.

### Task 2: Take Automated Screenshots

**Goal:** Capture a screenshot of a webpage without opening a window.

```bash
Ladybird --headless screenshot --window-width 1920 --window-height 1080 \
    --screenshot-delay 3 https://example.com
```

This waits 3 seconds for the page to fully render, then saves a 1920×1080 screenshot.

### Task 3: Run with a Custom User-Agent

**Goal:** Browse with a specific user-agent string to test site compatibility.

```bash
Ladybird --user-agent-preset Chrome https://example.com
```

### Task 4: Disable JavaScript for a Session

**Goal:** Browse without JavaScript execution for security testing or performance evaluation.

```bash
Ladybird --disable-scripting https://example.com
```

### Task 5: Enable Global Privacy Control

**Goal:** Signal to websites that you do not want your data sold or shared.

1. Open `about:settings` → Privacy
2. Enable the "Global Privacy Control" toggle

This adds the `Sec-GPC: 1` header to all HTTP requests.

### Task 6: Clear Browsing Data

**Goal:** Remove cached files, history, and site data.

1. Open `about:settings` → Privacy
2. Click "Clear Browsing Data"
3. Select what to clear: cached files, browsing history, site data
4. Choose time range: last hour, last 4 hours, today, or all time
5. Confirm

### Task 7: Add a Custom Search Engine

**Goal:** Use a search engine not in the built-in list.

1. Open `about:settings` → Search
2. Click "Add Custom Search Engine"
3. Enter a name (e.g., "DuckDuckGo")
4. Enter the URL template with `%s` as the query placeholder (e.g., `https://duckduckgo.com/?q=%s`)
5. Save, then select it as the default

### Task 8: Control Media Autoplay Per-Site

**Goal:** Allow autoplay on specific sites while blocking it everywhere else.

1. Open `about:settings` → Permissions
2. Ensure the global autoplay toggle is set to your preferred default (block or allow)
3. Add site-specific exceptions using the filter list

### Task 9: Use WebDriver for Automated Testing

**Goal:** Run automated browser tests using the W3C WebDriver protocol.

1. Build the WebDriver binary:

   ```bash
   python3 Meta/ladybird.py build WebDriver
   ```

2. Start the WebDriver server:

   ```bash
   ./Build/Release/bin/WebDriver --port 4444
   ```

3. Connect from your test framework (Selenium, WebdriverIO, etc.) using `http://localhost:4444`.

> [!NOTE]
> Ladybird's WebDriver supports one HTTP session at a time. Concurrent test sessions are not supported.

### Task 10: Force CPU Rendering

**Goal:** Run without GPU acceleration for troubleshooting rendering issues.

```bash
Ladybird --force-cpu-painting https://example.com
```

This uses the Skia CPU backend instead of Vulkan or Metal.

---

## 6. Troubleshooting

### Diagnostic Decision Tree

```text
Browser won't start?
├── Build error? → See Install Troubleshooting above
├── Crashes immediately? → Try --force-cpu-painting (GPU driver issue)
├── Black/blank window? → Check Vulkan/Metal driver support
└── Pages don't load? → Check DNS settings, try --dns-server 8.8.8.8

Page rendering issues?
├── Page is blank → Check if JavaScript is disabled (--disable-scripting)
├── Layout looks wrong → This is expected for complex sites; Ladybird is under active development
├── Missing images → The ImageDecoder process may have crashed; restart the browser
└── CSS not applied → Try reloading (Ctrl+R / Cmd+R)

Performance issues?
├── Slow page loads → Check DNS resolution (try --dot for faster DNS)
├── High memory usage → Each tab uses a separate process; close unused tabs
└── Stuttering/lag → Try --force-cpu-painting or update GPU drivers
```

### Error: Crash when loading any page

**Cause:** A regression in the rendering pipeline can cause crashes on page load. This has been observed in community reports (GitHub issue #8943).

**Solution:**

1. Update to the latest commit: `git pull && python3 Meta/ladybird.py build`
2. If the issue persists, try: `Ladybird --force-cpu-painting`
3. Report the crash with the URL at https://github.com/LadybirdBrowser/ladybird/issues

**Prevention:** Keep your build up to date; Ladybird receives frequent fixes.

### Error: Vulkan initialization failed

**Cause:** Missing or outdated Vulkan drivers.

**Solution:**

1. Install Vulkan drivers for your GPU (Mesa for AMD/Intel, NVIDIA proprietary driver)
2. Verify with: `vulkaninfo | head`
3. As a fallback, use CPU rendering: `Ladybird --force-cpu-painting`

### Error: DNS resolution failures with custom DNS

**Cause:** Misconfigured DNS server address or blocked port.

**Solution:**

1. Verify the DNS server is reachable: `dig @<server> example.com`
2. For DNS-over-TLS, ensure port 853 is not blocked by your firewall
3. Reset to system DNS in `about:settings` → Network → set "Upstream DNS" to "System"

> [!CAUTION]
> A misconfigured custom DNS will prevent ALL page loads. If you cannot access `about:settings`, restart with: `Ladybird --dns-server 8.8.8.8`

### Error: Build fails with "call stack size exceeded"

**Cause:** Deep JavaScript recursion or an unusually complex page.

**Solution:** This is an internal engine limitation. Report the URL as a bug.

### Error: WebDriver session creation fails

**Cause:** Another WebDriver session is already active, or the browser process failed to launch.

**Solution:**

1. Ensure no other WebDriver session is running (only one HTTP session at a time)
2. Check that the Ladybird binary is built and accessible
3. Verify the WebDriver port is not in use: `lsof -i :4444`

### Error: Fonts render incorrectly (Linux)

**Cause:** Missing fontconfig or freetype development libraries at build time.

**Solution:**

1. Install font libraries: `sudo apt install libfontconfig-dev libfreetype-dev libharfbuzz-dev`
2. Rebuild: `python3 Meta/ladybird.py build`
3. Alternatively, force fontconfig usage: `Ladybird --force-fontconfig`

### Error: High file descriptor usage / "Too many open files"

**Cause:** Ladybird's multi-process architecture uses many file descriptors for IPC.

**Solution:** Ladybird automatically tries to raise `RLIMIT_NOFILE` to 8192 on startup. If this fails, manually increase it:

```bash
ulimit -n 8192
Ladybird
```

> [!WARNING]
> On systems with restrictive resource limits (containers, shared hosting), you may need to configure the limit in your shell profile or systemd unit file.

---

## 7. FAQ

### General

**Q: Is Ladybird ready for daily use?**

Ladybird is under active development and not yet feature-complete. Many websites work, but complex web applications may encounter rendering or functionality issues. It is best used for testing, development, and contributing to the project.

**Q: What rendering engine does Ladybird use?**

Ladybird uses its own rendering engine, not Blink (Chromium) or Gecko (Firefox). The HTML/CSS engine is in `Libraries/LibWeb`, the JavaScript engine is in `Libraries/LibJS`, and rendering is powered by Skia with Vulkan or Metal backends.

**Q: What JavaScript engine does Ladybird use?**

LibJS — a custom ECMAScript engine with a Rust-based parser and bytecode interpreter. It includes an assembly-level JIT interpreter (AsmIntGen) for x86_64 and AArch64 that uses a threaded-dispatch architecture for performance-critical bytecode execution.

**Q: Does Ladybird support extensions/add-ons?**

Not currently. Extension support is not yet implemented.

**Q: Which platforms are supported?**

Linux (x86_64, AArch64), macOS (Apple Silicon and Intel), Windows (x86_64), FreeBSD, and Android (experimental).

### Building

**Q: How long does the first build take?**

The first build includes compiling all vcpkg dependencies (Skia, Qt/GTK, FFmpeg, curl, etc.), which can take 30-90 minutes depending on hardware and parallelism. Subsequent rebuilds are incremental and much faster.

**Q: Can I use a system-installed Qt instead of vcpkg?**

The build system uses vcpkg to manage dependencies for reproducibility. Using system Qt is possible but not officially supported and may require manual CMake configuration.

**Q: How do I update to the latest version?**

```bash
cd ladybird
git pull
python3 Meta/ladybird.py build
```

### Usage

**Q: How do I change the default search engine?**

Open `about:settings` → Search, and select your preferred engine from the dropdown or add a custom one.

**Q: Can I import bookmarks from another browser?**

Not currently. Bookmark import/export is not yet implemented.

**Q: How do I access developer tools?**

Launch with `--devtools` to start the Firefox DevTools protocol server, then connect from Firefox's remote debugging interface.

**Q: Does Ladybird support WebAssembly?**

Yes. LibWasm provides WebAssembly execution support.

**Q: Does Ladybird support media playback (audio/video)?**

Yes. Media decoding is handled via FFmpeg (bundled via vcpkg) supporting H.264, VP8/VP9, AV1, Opus, Vorbis, and other codecs.

**Q: What is the `--force-new-process` flag for?**

It forces Ladybird to start as a completely new instance rather than connecting to an existing one (relevant on GTK where D-Bus activation can reuse a running instance). It also disables the SQL database for that session and enables partitioned disk caching.

---

_Generated May 2026 from LadybirdBrowser/ladybird at de7ed9a. AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it. Unofficial; not affiliated with or reviewed by the project._
