lightpanda-browser

Building from Source

Lightpanda Browser is written in Zig and depends on several native libraries including V8, libcurl, and html5ever. This guide walks through installing prerequisites, building the browser, and configuring development options.

Prerequisites: Before building, make sure you are comfortable with command-line development tools. See Overview for an introduction to the project.


System Requirements

Building Lightpanda requires the following core tools:

Tool Version Purpose
Zig 0.15.2 (exact) Primary build system and language
Rust stable Required for html5ever HTML parser
Git any recent Cloning the repository
Make any recent Convenience build targets

Zig must be installed at exactly version 0.15.2. Other versions are not guaranteed to work because Zig does not yet have a stable ABI.

Platform-Specific Dependencies

Debian / Ubuntu

Install the system packages needed to compile V8 and other native dependencies:

sudo apt install xz-utils ca-certificates \
    pkg-config libglib2.0-dev \
    clang make curl git

Then install Rust via the official installer:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

macOS

On macOS, you need CMake (for BoringSSL) and Rust:

brew install cmake
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Xcode Command Line Tools must also be installed. If you have not already done so:

xcode-select --install

Nix

If you use Nix, the project includes a flake.nix that provides a complete development shell with all dependencies:

nix develop

This sets up a FHS-compliant environment containing Zig 0.15.2, Rust, Python 3, CMake, pkg-config, GCC, and all required libraries (expat, glib, glibc, zlib). No additional manual installation is needed.


Cloning the Repository

git clone https://github.com/lightpanda-io/browser.git
cd browser

Build Commands

Quick Build with Make

The Makefile provides convenient targets for common workflows:

# Release build (includes v8 snapshot for faster startup)
make build

# Debug build
make build-dev

The release build (make build) performs two steps automatically:

  1. Generates a V8 snapshot in ReleaseFast mode
  2. Compiles the browser in ReleaseFast mode using the embedded snapshot

The resulting binary is placed at ./zig-out/bin/lightpanda.

Using Zig Directly

You can also invoke the Zig build system directly for more control:

# Default (debug) build
zig build

# Build and run immediately
zig build run

# Release build for maximum performance
zig build -Doptimize=ReleaseFast

Build Options

The build.zig file exposes several configuration options:

Option Type Description
optimize enum Optimization level: Debug, ReleaseSafe, ReleaseFast, ReleaseSmall
snapshot_path string Path to a prebuilt V8 snapshot binary
prebuilt_v8_path string Path to a prebuilt libc_v8.a to skip V8 compilation
git_commit string Git commit hash embedded in the binary (defaults to "dev")
tsan bool Enable Thread Sanitizer
asan bool Enable Address Sanitizer
csan enum Enable C Sanitizers

Example with multiple options:

zig build -Doptimize=ReleaseFast -Dgit_commit=$(git rev-parse --short HEAD)

V8 Snapshots

Lightpanda uses V8 snapshots to dramatically reduce startup time. A snapshot serializes the initial JavaScript heap state so it does not need to be rebuilt on every launch.

How Snapshots Work

By default, Lightpanda creates the V8 snapshot at runtime during startup. For production or benchmarking, you should pre-generate and embed the snapshot into the binary.

Generating a Snapshot

zig build snapshot_creator -- src/snapshot.bin

This produces a snapshot.bin file containing the serialized V8 heap.

Building with an Embedded Snapshot

zig build -Dsnapshot_path=../../snapshot.bin

The Makefile automates this two-step process. When you run make build, it first generates the snapshot in ReleaseFast mode and then compiles the browser with the snapshot embedded.


Native Dependencies

Lightpanda links against several native libraries, all managed through the Zig build system via build.zig.zon dependency declarations. You do not need to install these manually; the build system fetches and compiles them automatically.

V8 (JavaScript Engine)

The V8 engine is provided by zig-v8-fork, a Zig-compatible fork of the V8 bindings. V8 compilation is the most time-consuming part of the build and may take 10-30 minutes on first build. The compiled artifact is cached in .lp-cache/ for subsequent builds.

If you have a prebuilt libc_v8.a, you can skip V8 compilation entirely:

zig build -Dprebuilt_v8_path=/path/to/libc_v8.a

html5ever (HTML Parser)

The HTML parser uses Rust’s html5ever via Cargo. The Zig build system invokes cargo build automatically to compile the litefetch_html5ever static library. This is why Rust is a required prerequisite.

libcurl (HTTP Client)

Libcurl is built from source along with its dependencies:

On macOS, the build also links against CoreFoundation and SystemConfiguration frameworks for proxy support.

Dependency Versions

Current dependency versions (from build.zig.zon):

Library Version
curl 8.18.0
zlib 1.3.2
Brotli 1.2.0
nghttp2 1.68.0
BoringSSL latest (git)

Running the Browser

After building, you can run Lightpanda directly:

# Run from the build output
./zig-out/bin/lightpanda serve --host 127.0.0.1 --port 9222

# Or build and run in one step
zig build run -- serve --host 127.0.0.1 --port 9222

For debug builds with additional logging:

make run-debug

Code Formatting

The Zig build system includes a formatting check step. By default, zig build verifies that all source files follow standard Zig formatting:

# Check formatting without building
zig build fmt

# Auto-format all source files
zig fmt src/ build.zig build.zig.zon

Formatting is checked automatically during the build. If any files are not formatted correctly, the build will fail with a formatting error.


Build Artifacts

After a successful build, the output is organized as follows:

browser/
├── zig-out/
│   └── bin/
│       ├── lightpanda                    # Main browser binary
│       └── lightpanda-snapshot-creator   # Snapshot generation tool
├── .lp-cache/                            # Cached V8 build artifacts
└── src/snapshot.bin                      # Generated V8 snapshot (if created)

The zig-out/ directory is the standard Zig output directory. The .lp-cache/ directory contains cached V8 compilation artifacts and can be safely deleted if you need a clean V8 rebuild.


Troubleshooting

V8 Build Fails

V8 compilation requires significant memory (4GB+ recommended). If the build is killed by the OOM killer, try closing other applications or increasing available memory. The V8 build also requires clang on Linux — make sure it is installed.

html5ever / Cargo Errors

Ensure Rust is installed and cargo is in your PATH. The html5ever build requires the Rust stable toolchain:

rustup default stable
rustup update

Zig Version Mismatch

Lightpanda requires Zig 0.15.2 exactly. Check your version with:

zig version

If you have a different version, download the correct one from ziglang.org/download. The Nix devShell automatically provides the correct version.

macOS Linker Issues

If you encounter linker errors related to frameworks on macOS, ensure Xcode Command Line Tools are up to date:

sudo xcode-select --switch /Applications/Xcode.app

Clean Rebuild

To perform a completely clean rebuild:

rm -rf zig-out zig-cache .lp-cache
zig build

Development Workflow

A typical development cycle looks like this:

  1. Make code changes in src/
  2. Build in debug mode: make build-dev or zig build
  3. Run unit tests: make test
  4. Test manually: zig build run -- serve --host 127.0.0.1 --port 9222
  5. Check formatting: zig build fmt

For performance testing, use a release build:

make build
./zig-out/bin/lightpanda serve --host 127.0.0.1 --port 9222