AK (short for Agnostic Kit) is the foundational C++ utility library used throughout every component of Ladybird. Rather than depending on the C++ Standard Library, the codebase relies on AK’s own containers, string types, smart pointers, and error-handling primitives. This design gives Ladybird consistent semantics for allocation failures, a unified ownership model, and string types that are always well-formed UTF-8 — all without pulling in the inconsistencies and platform variation that come withDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/ladybirdBrowser/ladybird/llms.txt
Use this file to discover all available pages before exploring further.
<vector>, <string>, and <memory>.
AK is not formally documented beyond the source headers and existing usage in the codebase. The best way to learn any AK type is to read its header in
AK/ and look at how it is used across Libraries/.Why AK Exists
The C++ STL was not designed with the kind of consistent, propagatable error handling that Ladybird requires. STL containers throw exceptions on allocation failure or silently invoke undefined behaviour;std::string makes no UTF-8 guarantees; and STL smart pointers carry their own ownership conventions that do not map cleanly onto a browser’s object graph. AK solves each of these problems in one place so that every library built on top of it shares the same idioms.
Error Handling: ErrorOr, TRY(), and MUST()
Error Handling: ErrorOr, TRY(), and MUST()
The cornerstone of AK’s error-handling story is Because ordinary C++ constructors cannot return
ErrorOr<T> — a return type that holds either a successful value of type T or an Error. Functions that can fail return ErrorOr<T> instead of throwing or returning raw integers.Two companion macros make working with ErrorOr<T> ergonomic:TRY(...)— evaluates the expression inside it. If the result is an error, the error is immediately returned from the enclosing function. If it succeeds, the macro evaluates to the unwrapped value. This is intentionally analogous to the?operator in Rust.MUST(...)— likeTRY, but asserts that the expression must succeed. Use this only when a failure is logically impossible, or when a crash is the correct response to failure. Do not useMUSTas a shortcut for avoiding propagation; userelease_value_but_fixme_should_propagate_errors()to mark sites that need to be improved.
ErrorOr<T>, classes that need fallible initialisation use the fallible constructor pattern: a static create() function that returns ErrorOr<NonnullOwnPtr<T>>, performs all fallible operations, then calls the private constructor only on success.Smart Pointers: OwnPtr, RefPtr, and WeakPtr
Smart Pointers: OwnPtr, RefPtr, and WeakPtr
AK provides three families of smart pointer that make ownership explicit in every function signature and data member.
OwnPtr<T> / NonnullOwnPtr<T> — single-owner pointers. The object is destroyed when the OwnPtr goes out of scope. These pointers cannot be copied; ownership is transferred by moving. NonnullOwnPtr adds the invariant that the pointer is never null, making it suitable as a return type from factory functions and as an argument type that must not be null.RefPtr<T> / NonnullRefPtr<T> — shared-ownership pointers backed by reference counting. A class becomes reference-countable by inheriting from RefCounted<T>. The object is destroyed when the last RefPtr referencing it is released.WeakPtr<T> — a non-owning pointer to a Weakable<T> object. When the pointed-to object is destroyed, the WeakPtr automatically becomes null, making it safe to observe without extending object lifetime.Containers
Containers
AK ships a complete set of allocation-aware containers. Each container exposes both a fallible API (prefixed with
try_, returns ErrorOr) and an infallible API (asserts on failure). In contexts where OOM must be handled gracefully, always use the try_ variants with TRY.| Type | Description |
|---|---|
Vector<T> | Dynamic resizable array, the most common list type. Supports an optional inline capacity as a second template argument. |
Array<T, N> | Fixed-size inline array (like std::array). Never allocates on the heap. |
FixedArray<T> | Runtime-sized array whose size is fixed at construction; never reallocates. |
HashMap<K, V> | Hash map backed by open-address hashing. |
HashTable<T> | Hash set. |
Queue<T> | FIFO queue backed by Vector. |
CircularQueue<T> | Fixed-capacity circular queue; capacity is set at compile time. |
CircularBuffer | Byte-oriented circular buffer; capacity is set at construction time. |
BinaryHeap<T> | Max-heap for priority queuing. |
DoublyLinkedList<T> | Standard doubly-linked list. |
IntrusiveList<T> | Intrusive doubly-linked list; membership metadata lives inside the node, so insertion never allocates. Ideal for OOM-durable data structures. |
RedBlackTree<K, V> | Balanced BST for ordered key-value storage. |
Span<T> | Non-owning view over a contiguous range of T. Prefer Span for APIs that do not need to own data or handle resizing. |
String Types
String Types
AK provides several string types, each serving a distinct purpose:
Format strings use a Custom types can be made formattable by specialising The
| Type | Description |
|---|---|
String | The primary string type. Always valid UTF-8. Immutable value type with small-string optimisation. |
StringView | Non-owning view over a String, ByteString, or string literal. Zero-cost to construct from a "..."sv literal at compile time. |
ByteString | A mutable, heap-allocated string of arbitrary bytes (no UTF-8 guarantee). Retained for compatibility; prefer String for new code. |
StringBuilder | Incrementally builds a ByteString or String from fragments, with appendff() for format-string appending. |
FlyString | An interned string type. Two FlyString values containing equal content share the same backing allocation, making equality comparison O(1). |
Utf8View | An iterator over the Unicode code points of a UTF-8 byte sequence. |
Utf16String / Utf16View | UTF-16 string and view, used where the web platform mandates UTF-16 (e.g., JavaScript strings). |
{}-based syntax similar to C++20 std::format. Format specifiers go after a : inside the braces; indices can be explicit ({0}, {1}). Format strings are checked at compile time.AK::Formatter<T>:"foo"sv literal operator constructs a StringView from a string literal with no runtime cost — the length is computed at compile time and the data resides in the binary’s read-only section.Numerics and Math
Numerics and Math
AK provides several numeric utilities designed to catch common integer bugs:
Checked<T>— wraps an integer type and detects overflow. Any arithmetic that overflows sets a sticky flag that can be checked viahas_overflow()before using the result.UFixedBigInt<N>— a fixed-width big integer (width specified in bits at compile time) used in JavaScript numeric operations. Defined inAK/UFixedBigInt.h, built on the low-levelAK/BigIntBase.hhelpers. Arbitrary-precision big integers (UnsignedBigInteger,SignedBigInteger) live inLibCrypto/BigInt/.SaturatingMath.h— saturating arithmetic helpers that clamp at the integer limits rather than wrapping.IntegralMath.h— compile-time and runtime integer utilities (power-of-two rounding, log2, etc.).FloatingPoint.h— bit-level access to IEEE 754 floating-point values.Math.h— AK’s own implementations of common math functions.
General Utilities
General Utilities
AK includes a broad set of single-purpose utilities used throughout the codebase:
| Header | Purpose |
|---|---|
Optional<T> | Nullable value wrapper (similar to std::optional). |
Variant<Ts...> | Type-safe discriminated union. |
Function<T> | Type-erased callable, similar to std::function. |
Badge<T> | Compile-time access control: allows only class T to call a function tagged with Badge<T>. |
Atomic<T> | Lock-free atomic variable. |
ScopeGuard | RAII scope-exit callback. |
TemporaryChange<T> | Saves a variable’s value and restores it when the guard goes out of scope. |
SourceLocation | Captures __FILE__/__LINE__/__FUNCTION__ as a default function argument (C++20 std::source_location equivalent). |
NeverDestroyed<T> | Holds a T in static storage without ever calling its destructor. |
LexicalPath | Parses and manipulates file system paths lexically. |
JsonValue / JsonObject / JsonArray | Full JSON parser and serialiser. |
Base64 | Base64 encode/decode with ErrorOr-returning interface. |
