| Agents SDKs | Python · Node.js |
-| LiveKit SDKs | Browser · Swift · Android · Flutter · React Native · Rust · Node.js · Python · Unity · Unity (WebGL) · ESP32 · C++ |
+| LiveKit SDKs | Browser · Swift · Android · Flutter · React Native · Rust · Node.js · Python · Unity · Unity (WebGL) · ESP32 · C++ |
| Starter Apps | Python Agent · TypeScript Agent · React App · SwiftUI App · Android App · Flutter App · React Native App · Web Embed |
| UI Components | React · Android Compose · SwiftUI · Flutter |
-| Server APIs | Node.js · Golang · Ruby · Java/Kotlin · Python · Rust · PHP (community) · .NET (community) |
+| Server APIs | Node.js · Golang · Ruby · Java/Kotlin · Python · Rust · PHP (community) · .NET (community) |
| Resources | Docs · Docs MCP Server · CLI · LiveKit Cloud |
| LiveKit Server OSS | LiveKit server · Egress · Ingress · SIP |
| Community | Developer Community · Slack · X · YouTube |
diff --git a/README_BUILD.md b/README_BUILD.md
deleted file mode 100644
index 0c061bb2..00000000
--- a/README_BUILD.md
+++ /dev/null
@@ -1,338 +0,0 @@
-# Build Guide
-
-## Prerequisites
-
-### Required Tools
-1. **CMake** (>= 3.20)
-2. **Rust and Cargo** - For building the Rust FFI layer
-3. **C++ Compiler**
- - Windows: Visual Studio 2019 or later
- - Linux: GCC 9+ or Clang 10+
- - macOS: Xcode 12+
-
-### Dependency Management
-
-This project uses different dependency management strategies per platform:
-
-| Platform | Package Manager | Dependencies |
-|----------|-----------------|-------------|
-| Windows | vcpkg (bundled) | protobuf, abseil (DLLs included in distribution) |
-| Linux | apt/dnf | `libprotobuf-dev libabsl-dev libssl-dev` |
-| macOS | Homebrew | `protobuf abseil` |
-
-#### Windows: Install vcpkg
-
-```powershell
-git clone https://github.com/microsoft/vcpkg.git
-cd vcpkg
-.\bootstrap-vcpkg.bat
-$env:VCPKG_ROOT = "$(Get-Location)"
-```
-
-#### Linux: Install Dependencies
-
-```bash
-# Ubuntu/Debian
-sudo apt update && sudo apt install -y \
- build-essential cmake ninja-build pkg-config \
- llvm-dev libclang-dev clang \
- libprotobuf-dev protobuf-compiler libabsl-dev \
- libssl-dev libva-dev libdrm-dev libgbm-dev libx11-dev libgl1-mesa-dev
-```
-
-#### macOS: Install Dependencies
-
-```bash
-brew install cmake ninja protobuf abseil
-```
-
-## Quick Start
-
-### Method 1: Using Build Scripts (Recommended)
-
-The project provides `build.cmd` (Windows) and `build.sh` (Linux/macOS) scripts for simplified building.
-
-**Windows:**
-```powershell
-# Set vcpkg root (required for Windows)
-$env:VCPKG_ROOT = "C:\path\to\vcpkg"
-
-# Build Release version
-.\build.cmd release
-
-# Build Release with examples
-.\build.cmd release-examples
-
-# Build Debug version
-.\build.cmd debug
-
-# Build Debug with examples
-.\build.cmd debug-examples
-
-# Clean build artifacts
-.\build.cmd clean
-
-# Full clean (C++ + Rust + generated files)
-.\build.cmd clean-all
-```
-
-**Linux:**
-```bash
-# Install system dependencies first (see Prerequisites above)
-
-# Build Release version
-./build.sh release
-
-# Build Release with examples
-./build.sh release-examples
-
-# Build Debug version
-./build.sh debug
-
-# Build Debug with examples
-./build.sh debug-examples
-
-# Clean build artifacts
-./build.sh clean
-
-# Full clean
-./build.sh clean-all
-```
-
-**macOS:**
-```bash
-# Install Homebrew dependencies first (see Prerequisites above)
-
-# Build Release version
-./build.sh release
-
-# Build Release with examples
-./build.sh release-examples
-
-# Build Debug version
-./build.sh debug
-
-# Build Debug with examples
-./build.sh debug-examples
-```
-
-#### Important Notes for Linux
-
-Before building on Linux (especially Ubuntu/WSL), you may need to set environment variables to avoid common build errors.
-
-**Set Build Environment Variables:**
-```bash
-# Suppress deprecated warnings from WebRTC (required for newer GCC versions)
-export CXXFLAGS="-Wno-deprecated-declarations"
-export CFLAGS="-Wno-deprecated-declarations"
-
-# Required for Rust bindgen to find libclang
-export LIBCLANG_PATH=/usr/lib/llvm-14/lib # Adjust version as needed
-```
-
-**Common Issues:**
-
-1. **Missing proto files or client-sdk-rust directory**
- - Solution: Initialize git submodules:
- ```bash
- git submodule update --init --recursive
- ```
-
-2. **Deprecated declaration errors during compilation**
- - Cause: Newer GCC versions (12/13/14) are stricter with WebRTC legacy code
- - Solution: Set `CXXFLAGS` and `CFLAGS` as shown above
-
-3. **Rust bindgen fails with "unable to find libclang"**
- - Cause: Rust bindgen cannot locate libclang library
- - Solution: Set `LIBCLANG_PATH` environment variable pointing to your LLVM installation
-
-### Method 2: Using vcpkg Manifest Mode
-
-vcpkg will automatically install all required dependencies based on `vcpkg.json`.
-
-**Windows:**
-```powershell
-# Configure project
-cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=/scripts/buildsystems/vcpkg.cmake
-
-# Build
-cmake --build build --config Release
-
-# Optional: Build with examples
-cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=/scripts/buildsystems/vcpkg.cmake -DLIVEKIT_BUILD_EXAMPLES=ON -DVCPKG_MANIFEST_FEATURES=examples
-cmake --build build --config Release
-```
-
-**Linux/macOS:**
-```bash
-# Configure project
-cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=Release
-
-# Build
-cmake --build build
-
-# Optional: Build with examples
-cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=Release -DLIVEKIT_BUILD_EXAMPLES=ON -DVCPKG_MANIFEST_FEATURES=examples
-cmake --build build
-```
-
-### Method 3: Manual Dependency Installation
-
-If you prefer not to use vcpkg, you can install dependencies manually:
-
-#### Required Dependencies
-- **Protobuf** (>= 5.29)
- - Windows: `vcpkg install protobuf:x64-windows`
- - Linux: `sudo apt install libprotobuf-dev protobuf-compiler`
- - macOS: `brew install protobuf`
-
-- **Abseil** (Required for Protobuf >= 6)
- - Windows: `vcpkg install abseil:x64-windows`
- - Linux: `sudo apt install libabsl-dev`
- - macOS: `brew install abseil`
-
-- **OpenSSL** (Linux only)
- - Linux: `sudo apt install libssl-dev`
-
-#### Build Command
-```bash
-cmake -B build -S . -DCMAKE_BUILD_TYPE=Release
-cmake --build build
-```
-
-## Build Output
-
-After a successful build, you will find the following in the build directories:
-
-```
-build-release/ # Release build output
-├── lib/
-│ ├── livekit.lib / liblivekit.a # Main SDK static library
-│ ├── livekit_ffi.dll / .so / .dylib # Rust FFI dynamic library
-│ └── (Windows only: protobuf, abseil DLLs)
-├── include/ # Public headers (auto-synced)
-│ └── livekit/
-└── bin/ # Example executables (with examples enabled)
- ├── SimpleRoom
- ├── SimpleRpc
- ├── SimpleDataStream
- └── liblivekit_ffi.so / .dylib # (Linux/macOS: copied for runtime)
-```
-
-## Integrating into Your Project
-
-### Using CMake
-
-```cmake
-# Method 1: As a subdirectory
-add_subdirectory(path/to/client-sdk-cpp)
-target_link_libraries(your_target PRIVATE livekit)
-
-# Method 2: Using find_package (requires prior installation)
-find_package(livekit REQUIRED)
-target_link_libraries(your_target PRIVATE livekit)
-```
-
-### Manual Linking
-
-1. Add include path: `build/include`
-2. Link static library:
- - Windows: `build/lib/livekit.lib`
- - Linux: `build/lib/liblivekit.a`
- - macOS: `build/lib/liblivekit.a`
-3. Link/Deploy Rust FFI dynamic library:
- - Windows: Link `livekit_ffi.dll.lib`, deploy `livekit_ffi.dll` with your exe
- - Linux: Deploy `liblivekit_ffi.so` in same directory as your executable
- - macOS: Deploy `liblivekit_ffi.dylib` in same directory as your executable
-4. Link platform-specific system libraries
-
-> **Important**: On Linux/macOS, the `.so`/`.dylib` must be in the same directory as your executable (RPATH is set to `$ORIGIN` / `@executable_path`).
-
-**Windows system libraries:**
-```
-ntdll userenv winmm iphlpapi msdmo dmoguids wmcodecdspuuid
-ws2_32 secur32 bcrypt crypt32
-```
-
-**macOS frameworks:**
-```
-CoreAudio AudioToolbox CoreFoundation Security CoreGraphics
-CoreMedia VideoToolbox AVFoundation CoreVideo Foundation
-AppKit QuartzCore OpenGL IOSurface Metal MetalKit ScreenCaptureKit
-```
-
-**Linux libraries:**
-```
-OpenSSL::SSL OpenSSL::Crypto
-```
-
-## CMake Options
-
-| Option | Default | Description |
-|--------|---------|-------------|
-| `LIVEKIT_BUILD_EXAMPLES` | OFF | Build example applications |
-| `LIVEKIT_VERSION` | "0.1.0" | SDK version number |
-| `LIVEKIT_USE_VCPKG` | ON | Use vcpkg for dependency management |
-
-## Troubleshooting
-
-### Q: Rust code recompiles after modifying C++ code?
-A: This has been fixed. Rust code only recompiles when Rust source files change or the Rust library doesn't exist.
-
-### Q: Cannot find Protobuf or other dependencies?
-A: Make sure you're using the correct CMake toolchain file:
-```bash
--DCMAKE_TOOLCHAIN_FILE=/scripts/buildsystems/vcpkg.cmake
-```
-
-### Q: Linking fails on Linux?
-A: Ensure you have OpenSSL development packages installed:
-```bash
-sudo apt install libssl-dev
-```
-
-### Q: How to clean the build?
-A: Use the CMake-provided clean targets:
-```bash
-# Clean CMake build artifacts
-cmake --build build --target clean
-
-# Clean Rust build artifacts
-cmake --build build --target cargo_clean
-
-# Clean generated protobuf files
-cmake --build build --target clean_generated
-
-# Complete clean (including deletion of build directory)
-cmake --build build --target clean_all
-```
-
-## Example Applications
-
-Example applications are located in the `examples/` directory:
-
-- **SimpleRoom** - Basic room connection and audio/video handling
-- **SimpleRpc** - RPC call examples
-- **SimpleDataStream** - Data stream transmission examples
-
-Please refer to the README in each example directory for more details.
-
-## Platform-Specific Notes
-
-### Windows
-- Recommended: Visual Studio 2019 or later
-- Architecture: x64
-
-### macOS
-- Requires macOS 12.3+ (ScreenCaptureKit support)
-- Requires Xcode Command Line Tools
-
-### Linux
-- Tested on: Ubuntu 20.04+
-- Requires complete development toolchain
-
-## Support
-
-- GitHub Issues: https://github.com/livekit/client-sdk-cpp/issues
-- LiveKit Documentation: https://docs.livekit.io/
-
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 00000000..fd06e209
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,14 @@
+# Repository Documentation
+
+Additional documentation for the SDK.
+
+- [Building](building.md) — prerequisites, build scripts, CMake presets,
+ vcpkg, Docker, integration into your CMake project, troubleshooting.
+- [Logging](logging.md) — compile-time vs runtime filtering, log levels,
+ custom sinks (file, JSON, ROS2 `RCLCPP_*` macros).
+- [Tracing](tracing.md) — Chromium-format performance traces, viewing in
+ `chrome://tracing` and Perfetto.
+- [Testing](testing.md) — unit, integration, and stress test suites; env
+ vars; token-helper script for local `livekit-server --dev` runs.
+- [Developer tools](tools.md) — `clang-tidy`, `clang-format`, `valgrind`,
+ Doxygen, pre-commit hook, Rust submodule recovery tips.
diff --git a/docs/building.md b/docs/building.md
new file mode 100644
index 00000000..9b1234bb
--- /dev/null
+++ b/docs/building.md
@@ -0,0 +1,369 @@
+# Build guide
+
+This document covers everything you need to build the LiveKit C++ SDK from
+source: requirements, cloning the repository, the build scripts, advanced
+CMake/vcpkg flows, and Docker.
+
+For a quick `clone + build` recipe, see the main README. This guide is the
+long form.
+
+## Prerequisites
+
+### Common to all platforms
+
+- **CMake** ≥ 3.20
+- **Rust / Cargo** — latest stable toolchain (for building the Rust FFI layer).
+ Install via [rustup](https://rustup.rs/).
+- **Git LFS** — required for examples that pull test media assets.
+- **Protobuf** ≥ 5.29
+- **Abseil** — always required (used by Protobuf 5.x+)
+
+### Platform-specific toolchains
+
+| Platform | Compiler | Package manager |
+|----------|----------|-----------------|
+| Windows | Visual Studio 2019+ (MSBuild or Ninja) | vcpkg (see below) |
+| Linux | GCC 9+ or Clang 10+ | `apt` / `dnf` (or vcpkg) |
+| macOS | Xcode 12+ (macOS 12.3+ for ScreenCaptureKit) | Homebrew (or vcpkg) |
+
+## Clone the repository
+
+The SDK depends on the [`client-sdk-rust`](https://github.com/livekit/rust-sdks)
+submodule (recursive), so always clone with submodules:
+
+```bash
+# Option 1: clone with submodules in one step
+git clone --recurse-submodules https://github.com/livekit/client-sdk-cpp.git
+
+# Option 2: clone first, then initialize submodules
+git clone https://github.com/livekit/client-sdk-cpp.git
+cd client-sdk-cpp
+git submodule update --init --recursive
+
+# Pull Git LFS assets if you want to run the integration tests:
+git lfs pull
+```
+
+## Recommended setup
+
+These are the exact packages our CI uses. They will also work for examples.
+
+### macOS
+
+```bash
+brew install cmake ninja protobuf abseil rust
+```
+
+### Ubuntu / Debian
+
+```bash
+sudo apt update && sudo apt install -y \
+ build-essential cmake ninja-build pkg-config \
+ llvm-dev libclang-dev clang \
+ libprotobuf-dev protobuf-compiler libabsl-dev \
+ libssl-dev
+
+# Install Rust if you don't already have it
+curl https://sh.rustup.rs -sSf | sh
+```
+
+If you plan to build the [example collection](https://github.com/livekit-examples/cpp-example-collection)
+(SDL-based renderer + camera/mic capture), also install:
+
+```bash
+sudo apt install -y \
+ libva-dev libdrm-dev libgbm-dev libx11-dev libgl1-mesa-dev \
+ libxext-dev libxcomposite-dev libxdamage-dev libxfixes-dev \
+ libxrandr-dev libxi-dev libxkbcommon-dev \
+ libasound2-dev libpulse-dev \
+ libwayland-dev libdecor-0-dev
+```
+
+### Windows
+
+```powershell
+# Set VCPKG_ROOT once and bootstrap vcpkg
+git clone https://github.com/microsoft/vcpkg.git
+.\vcpkg\bootstrap-vcpkg.bat
+$env:VCPKG_ROOT = "$PWD\vcpkg"
+```
+
+CMake's vcpkg manifest mode (below) reads
+`vcpkg.json` and installs the rest automatically the first time you configure.
+
+## Build scripts (recommended)
+
+The repo ships with `build.sh` (Linux/macOS) and `build.cmd` (Windows) that
+wrap the right CMake preset for your platform and pick sensible defaults.
+
+**Linux/macOS:**
+```bash
+./build.sh release # Build Release
+./build.sh debug # Build Debug
+./build.sh release-examples # Release + examples
+./build.sh debug-examples # Debug + examples
+./build.sh release-tests # Release + tests
+./build.sh debug-tests # Debug + tests
+./build.sh release-all # Release + tests + examples
+./build.sh debug-all # Debug + tests + examples
+./build.sh clean # Clean CMake build artifacts + local-install
+./build.sh clean-all # Deep clean (C++ + Rust + local-install + generated files)
+```
+
+**Windows:**
+```powershell
+.\build.cmd release
+.\build.cmd debug
+.\build.cmd release-examples
+# ... same suffixes as build.sh
+```
+
+The build scripts pass an explicit job count to `cmake --build --parallel`. Set
+`CMAKE_BUILD_PARALLEL_LEVEL` to override the auto-detected logical CPU count.
+
+## Advanced: CMake presets
+
+For more control, drive CMake directly via the presets in
+[CMakePresets.json](../CMakePresets.json):
+
+```bash
+# Linux
+cmake --preset linux-release
+cmake --build --preset linux-release
+
+# macOS
+cmake --preset macos-release
+cmake --build --preset macos-release
+
+# Windows
+cmake --preset windows-release
+cmake --build --preset windows-release
+```
+
+Windows requires `VCPKG_ROOT` to be set:
+
+```powershell
+$env:VCPKG_ROOT = "C:\path\to\vcpkg"
+```
+
+## Advanced: vcpkg manifest mode
+
+vcpkg will automatically install all dependencies listed in
+[vcpkg.json](../vcpkg.json) the first time you configure with its toolchain
+file.
+
+**Windows:**
+```powershell
+cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=$env:VCPKG_ROOT\scripts\buildsystems\vcpkg.cmake
+cmake --build build --config Release
+
+# With examples:
+cmake -B build -S . `
+ -DCMAKE_TOOLCHAIN_FILE=$env:VCPKG_ROOT\scripts\buildsystems\vcpkg.cmake `
+ -DLIVEKIT_BUILD_EXAMPLES=ON -DVCPKG_MANIFEST_FEATURES=examples
+cmake --build build --config Release
+```
+
+**Linux/macOS:**
+```bash
+cmake -B build -S . \
+ -DCMAKE_TOOLCHAIN_FILE=/scripts/buildsystems/vcpkg.cmake \
+ -DCMAKE_BUILD_TYPE=Release
+cmake --build build
+
+# With examples:
+cmake -B build -S . \
+ -DCMAKE_TOOLCHAIN_FILE=/scripts/buildsystems/vcpkg.cmake \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DLIVEKIT_BUILD_EXAMPLES=ON -DVCPKG_MANIFEST_FEATURES=examples
+cmake --build build
+```
+
+## Building with Docker
+
+The Docker setup is split into a reusable base image (toolchain + system
+deps) and an SDK image layered on top. **Tested on Linux only.**
+
+```bash
+docker build -t livekit-cpp-sdk-base . -f docker/Dockerfile.base
+docker build --build-arg BASE_IMAGE=livekit-cpp-sdk-base \
+ -t livekit-cpp-sdk . -f docker/Dockerfile.sdk
+docker run -it --network host livekit-cpp-sdk:latest bash
+```
+
+If you're authoring your own Dockerfile, mirror the `ENV` block in
+[docker/Dockerfile.base](../docker/Dockerfile.base):
+
+```bash
+export CC=$HOME/gcc-14/bin/gcc
+export CXX=$HOME/gcc-14/bin/g++
+export LD_LIBRARY_PATH=$HOME/gcc-14/lib64:$LD_LIBRARY_PATH
+export PATH=$HOME/.cargo/bin:$PATH
+export PATH=$HOME/cmake-3.31/bin:$PATH
+```
+
+## CMake options
+
+| Option | Default | Description |
+|--------|---------|-------------|
+| `LIVEKIT_BUILD_EXAMPLES` | OFF | Build example applications |
+| `LIVEKIT_USE_SYSTEM_PROTOBUF` | OFF | Use system Protobuf instead of vcpkg's |
+| `LIVEKIT_LOG_LEVEL` | `TRACE` | Compile-time log threshold (see [logging.md](logging.md)) |
+| `LIVEKIT_VERSION` | repo-derived | SDK version string baked into the binary |
+
+## Build output
+
+After a successful build:
+
+```
+build-release/
+├── lib/
+│ ├── liblivekit.{a,lib} # Main SDK static library
+│ ├── liblivekit_ffi.{so,dylib} # Rust FFI dynamic library
+│ └── livekit_ffi.dll, *.lib # (Windows) FFI DLL + import lib
+├── include/ # Public headers (auto-synced)
+│ └── livekit/
+└── bin/ # Example/test executables
+ └── liblivekit_ffi.{so,dylib} # (Linux/macOS: copied for runtime)
+```
+
+## Integrating into your project
+
+### Using CMake
+
+```cmake
+# Method 1: as a subdirectory
+add_subdirectory(path/to/client-sdk-cpp)
+target_link_libraries(your_target PRIVATE livekit)
+
+# Method 2: find_package (after install)
+find_package(livekit REQUIRED)
+target_link_libraries(your_target PRIVATE livekit)
+```
+
+### Using prebuilt releases
+
+The easiest way to consume the SDK without building from source is via
+the [cpp-example-collection](https://github.com/livekit-examples/cpp-example-collection)
+helper, which downloads a release tarball at CMake configure time:
+
+```cmake
+include(LiveKitSDK.cmake) # pins or auto-resolves a release
+```
+
+See the example collection's
+[`LiveKitSDK.cmake`](https://github.com/livekit-examples/cpp-example-collection/blob/main/cmake/LiveKitSDK.cmake)
+for the full pattern.
+
+### Manual linking
+
+1. Add include path: `build-release/include`
+2. Link the static SDK library:
+ - Windows: `build-release/lib/livekit.lib`
+ - Linux: `build-release/lib/liblivekit.a`
+ - macOS: `build-release/lib/liblivekit.a`
+3. Link/deploy the Rust FFI dynamic library:
+ - Windows: link `livekit_ffi.dll.lib`, deploy `livekit_ffi.dll` next to your `.exe`
+ - Linux: deploy `liblivekit_ffi.so` next to your executable
+ - macOS: deploy `liblivekit_ffi.dylib` next to your executable
+4. Link platform system libraries (see below).
+
+> **Important:** On Linux/macOS the FFI shared library must live next to the
+> executable. RPATH is set to `$ORIGIN` (Linux) / `@loader_path` (macOS).
+
+**Windows system libraries:**
+```
+ntdll userenv winmm iphlpapi msdmo dmoguids wmcodecdspuuid
+ws2_32 secur32 bcrypt crypt32
+```
+
+**macOS frameworks:**
+```
+CoreAudio AudioToolbox CoreFoundation Security CoreGraphics
+CoreMedia VideoToolbox AVFoundation CoreVideo Foundation
+AppKit QuartzCore OpenGL IOSurface Metal MetalKit ScreenCaptureKit
+```
+
+**Linux libraries:**
+```
+OpenSSL::SSL OpenSSL::Crypto
+```
+
+### Runtime dependencies of prebuilt artifacts
+
+Whether protobuf / abseil / openssl need to be installed on the target
+machine depends on how the SDK binary was built:
+
+- **Windows** release artifacts use vcpkg triplet `x64-windows-static-md` —
+ protobuf and abseil are statically linked into the DLLs; no runtime install
+ needed.
+- **macOS** release artifacts (from our CI) do **not** dynamically depend on
+ protobuf / abseil / openssl. You can verify with `otool -L liblivekit.dylib`.
+- **Linux** depends on packaging. Check with `ldd liblivekit_ffi.so`; if any
+ of those are listed, install the corresponding `-dev` (build) or runtime
+ package (`libprotobuf32` / `libabsl` / `libssl3`) as appropriate.
+
+## Troubleshooting
+
+### Missing proto files or `client-sdk-rust` directory
+
+Initialize submodules:
+```bash
+git submodule update --init --recursive
+```
+
+### Deprecated-declaration errors on Linux
+
+Newer GCC versions (12+) are stricter with the WebRTC legacy code in the
+Rust submodule. If `./build.sh release` errors with `-Werror=deprecated-declarations`,
+relax it for the build:
+
+```bash
+export CXXFLAGS="-Wno-deprecated-declarations"
+export CFLAGS="-Wno-deprecated-declarations"
+```
+
+### Rust bindgen fails with "unable to find libclang"
+
+Install `libclang-dev` (Ubuntu) or `llvm` (macOS Homebrew). bindgen normally
+discovers libclang from the system paths once `libclang-dev` is installed; if
+not, point `LIBCLANG_PATH` at your LLVM's `lib` directory (e.g.
+`/usr/lib/llvm-18/lib` on Ubuntu 24.04).
+
+### Rust code recompiles after C++ edits
+
+This was a historical issue; Rust only recompiles now when Rust source files
+change or the Rust library is missing.
+
+### Cannot find Protobuf or other dependencies
+
+Make sure you're passing the vcpkg toolchain file:
+```bash
+-DCMAKE_TOOLCHAIN_FILE=/scripts/buildsystems/vcpkg.cmake
+```
+
+### `clang-tidy` on Windows
+
+Not currently supported via our scripts — the Visual Studio (MSBuild) CMake
+generator doesn't produce `compile_commands.json`. The Ninja generator does;
+see [tools.md](tools.md).
+
+### How do I deep-clean?
+
+```bash
+./build.sh clean-all # C++ + Rust + local-install + generated files
+```
+
+Or via CMake targets:
+
+```bash
+cmake --build build --target clean # CMake artifacts
+cmake --build build --target cargo_clean # Rust artifacts
+cmake --build build --target clean_generated # Generated protobuf headers
+cmake --build build --target clean_all # Full clean
+```
+
+## Support
+
+- GitHub Issues:
+- LiveKit Docs:
diff --git a/docs/logging.md b/docs/logging.md
new file mode 100644
index 00000000..1889479c
--- /dev/null
+++ b/docs/logging.md
@@ -0,0 +1,85 @@
+# Logging
+
+The SDK uses [spdlog](https://github.com/gabime/spdlog) internally but does
+**not** expose it in public headers. All log output goes through a thin public
+API in ``.
+
+## Two-tier filtering
+
+| Tier | When | How | Cost |
+|------|------|-----|------|
+| **Compile-time** | CMake configure | `-DLIVEKIT_LOG_LEVEL=WARN` | Zero — calls below the level are stripped from the binary |
+| **Runtime** | Any time after `initialize()` | `livekit::setLogLevel(LogLevel::Warn)` | Minimal — a level check before formatting |
+
+### Compile-time level (`LIVEKIT_LOG_LEVEL`)
+
+Set once when you configure CMake. Calls below this threshold are completely
+removed by the preprocessor — no format-string evaluation, no function call.
+
+```bash
+# Development (default): keep everything available
+cmake -DLIVEKIT_LOG_LEVEL=TRACE ..
+
+# Release: strip TRACE / DEBUG / INFO
+cmake -DLIVEKIT_LOG_LEVEL=WARN ..
+
+# Production: only ERROR and CRITICAL survive
+cmake -DLIVEKIT_LOG_LEVEL=ERROR ..
+```
+
+Valid values: `TRACE`, `DEBUG`, `INFO`, `WARN`, `ERROR`, `CRITICAL`, `OFF`.
+
+### Runtime level (`setLogLevel`)
+
+Among the levels that survived compilation you can still filter at runtime
+without rebuilding:
+
+```cpp
+#include
+
+livekit::initialize(); // default level: Info
+livekit::setLogLevel(livekit::LogLevel::Debug); // show more detail
+livekit::setLogLevel(livekit::LogLevel::Warn); // suppress info chatter
+```
+
+## Custom log callback
+
+Replace the default stderr sink with your own handler. This is the integration
+point for frameworks like ROS2 (`RCLCPP_*` macros), Android logcat, or any
+structured-logging pipeline:
+
+```cpp
+#include
+
+livekit::initialize();
+livekit::setLogLevel(livekit::LogLevel::Trace);
+
+livekit::setLogCallback(
+ [](livekit::LogLevel level,
+ const std::string &logger_name,
+ const std::string &message) {
+ // Route to your framework, e.g.:
+ // RCLCPP_INFO(get_logger(), "[%s] %s", logger_name.c_str(), message.c_str());
+ myLogger.log(level, logger_name, message);
+ });
+
+// Pass nullptr to restore the default stderr sink:
+livekit::setLogCallback(nullptr);
+```
+
+See the [`logging_levels/custom_sinks.cpp`](https://github.com/livekit-examples/cpp-example-collection/blob/main/logging_levels/custom_sinks.cpp)
+example for three copy-paste-ready patterns: a **file logger**, **JSON
+structured lines**, and a **ROS2 bridge** that maps `LogLevel` to `RCLCPP_*`
+macros.
+
+## Available log levels
+
+| Level | Typical use |
+|-------|-------------|
+| `Trace` | Per-frame / per-packet detail (very noisy) |
+| `Debug` | Diagnostic info useful during development |
+| `Info` | Normal operational messages (connection, track events) |
+| `Warn` | Unexpected but recoverable situations |
+| `Error` | Failures that affect functionality |
+| `Critical` | Unrecoverable errors |
+| `Off` | Suppress all output |
diff --git a/docs/testing.md b/docs/testing.md
new file mode 100644
index 00000000..120baabb
--- /dev/null
+++ b/docs/testing.md
@@ -0,0 +1,112 @@
+# Testing
+
+The SDK includes integration and stress tests using
+[Google Test](https://github.com/google/googletest).
+
+## Building the test binaries
+
+**Linux/macOS:**
+```bash
+./build.sh debug-tests # Build Debug with tests
+./build.sh release-tests # Build Release with tests
+```
+
+**Windows:**
+```powershell
+.\build.cmd debug-tests
+.\build.cmd release-tests
+```
+
+## Running tests
+
+After building, run tests using `ctest` or invoke the binaries directly:
+
+```bash
+# Run all tests via ctest
+cd build-debug
+ctest --output-on-failure
+
+# Or run test executables directly
+./build-debug/bin/livekit_integration_tests
+./build-debug/bin/livekit_stress_tests
+
+# Run specific test suites
+./build-debug/bin/livekit_integration_tests --gtest_filter="*Rpc*"
+./build-debug/bin/livekit_stress_tests --gtest_filter="*MaxPayloadStress*"
+```
+
+__Note:__ The tests require tokens and a running LiveKit server. See the section below for details.
+
+## Test binaries
+
+| Executable | Description |
+|------------|-------------|
+| `livekit_unit_tests` | Pure unit tests (no server required) |
+| `livekit_integration_tests` | Quick tests (~1-2 minutes) for SDK functionality |
+| `livekit_stress_tests` | Long-running tests (configurable, default 1 hour) |
+
+## Running a local LiveKit server for tests
+
+The integration and stress suites need a running LiveKit server. The easiest
+path is `livekit-server --dev`, which uses the well-known dev API
+key/secret (`devkey` / `secret`).
+
+Install [`livekit-server`](https://docs.livekit.io/home/self-hosting/local/)
+and start it with data tracks enabled:
+
+```bash
+livekit-server --dev
+```
+
+## Environment variables
+
+The integration and stress test suites (data tracks, RPC, media multistream,
+etc.) require a server URL and two participant tokens:
+
+```bash
+# Required
+export LIVEKIT_URL="ws://localhost:7880" # or wss://your-server.livekit.cloud
+export LIVEKIT_TOKEN_A=""
+export LIVEKIT_TOKEN_B=""
+
+# Optional (for stress tests)
+export RPC_STRESS_DURATION_SECONDS=3600 # Test duration (default: 1 hour)
+export RPC_STRESS_CALLER_THREADS=4 # Concurrent caller threads (default: 4)
+```
+
+### Generating tokens for the test suites
+
+The easiest path is to source the helper script, which mints both
+participant tokens against a local `livekit-server --dev` and exports
+`LIVEKIT_TOKEN_A`, `LIVEKIT_TOKEN_B`, and `LIVEKIT_URL` for the current shell:
+
+```bash
+source .token_helpers/set_data_track_test_tokens.bash
+```
+
+To generate tokens manually (e.g. against a non-default server), install
+[`livekit-cli`](https://docs.livekit.io/home/cli/cli-setup/) and run:
+
+```bash
+export LIVEKIT_TOKEN_A="$(lk token create --api-key devkey --api-secret secret -i cpp-test-a \
+ --join --valid-for 99999h --room cpp_data_track_test \
+ --grant '{"canPublish":true,"canSubscribe":true,"canPublishData":true}' \
+ --token-only)"
+export LIVEKIT_TOKEN_B="$(lk token create --api-key devkey --api-secret secret -i cpp-test-b \
+ --join --valid-for 99999h --room cpp_data_track_test \
+ --grant '{"canPublish":true,"canSubscribe":true,"canPublishData":true}' \
+ --token-only)"
+```
+
+## Test coverage
+
+- **SDK initialization**: initialize / shutdown lifecycle.
+- **Room**: room creation, options, connection.
+- **Audio frame**: frame creation, manipulation, edge cases.
+- **RPC**: round-trip calls, max payload (15 KB), timeouts, errors, concurrent calls.
+- **Stress**: high throughput, bidirectional RPC, memory pressure.
+
+## Memory checks (valgrind)
+
+Run `valgrind` against the test binaries to check for memory leaks and other
+issues. See [tools.md](tools.md) for the recipe.
diff --git a/docs/tools.md b/docs/tools.md
new file mode 100644
index 00000000..bbcd0124
--- /dev/null
+++ b/docs/tools.md
@@ -0,0 +1,163 @@
+# Developer tools
+
+This SDK uses several tools and checks to enforce code quality. All of these
+are also enforced in CI on PRs.
+
+## Clang tools
+
+- **`clang-tidy`** — static analysis. See [.clang-tidy](../.clang-tidy) for the
+ enabled checks. Enforced in CI on PR.
+- **`clang-format`** — code formatting and style consistency. See
+ [.clang-format](../.clang-format) for the rules. Enforced in CI on PR.
+
+> **Note (Windows):** `clang-tidy` is not currently driven by our scripts on
+> Windows. The MSBuild CMake generator doesn't emit
+> `compile_commands.json`, which `clang-tidy` requires. The Ninja generator
+> does, so manual invocation is possible. `clang-format` similarly needs to be
+> installed and run manually on Windows, pointing at the root `.clang-format`.
+
+### Install
+
+**macOS:**
+
+```bash
+brew install llvm
+```
+
+This installs `clang-format`, `clang-tidy`, and `run-clang-tidy`. Homebrew may
+ask you to add `/opt/homebrew/opt/llvm/bin` (Apple Silicon) or
+`/usr/local/opt/llvm/bin` (Intel) to your `PATH`.
+
+**Linux (Ubuntu/Debian):**
+
+```bash
+sudo apt-get install clang-format clang-tidy clang-tools
+```
+
+### Run `clang-tidy`
+
+1. Generate `compile_commands.json` and the protobuf headers via a release build:
+
+ ```bash
+ ./build.sh release
+ ```
+
+2. Run the wrapper, which uses the same file set, regex filters, and
+ `.clang-tidy` config as CI:
+
+ ```bash
+ ./scripts/clang-tidy.sh
+ ```
+
+The wrapper forwards extra arguments to `run-clang-tidy`:
+
+```bash
+./scripts/clang-tidy.sh -j 4 # Number of cores
+./scripts/clang-tidy.sh -checks='-*,misc-const-correctness' # Only specific checks
+./scripts/clang-tidy.sh -fix # Apply fixes
+```
+
+Output is captured to `clang-tidy.log` at the repo root, since the terminal
+buffer often can't hold all of it.
+
+### Run `clang-format`
+
+```bash
+./scripts/clang-format.sh
+```
+
+With no arguments, runs against every relevant file in the repository against
+the rules in `.clang-format`.
+
+```bash
+./scripts/clang-format.sh --fix # Rewrite files in place
+./scripts/clang-format.sh src/room.cpp include/livekit/room.h # Check just these files
+./scripts/clang-format.sh --fix src/room.cpp # Fix just this file
+```
+
+Output is captured to `clang-format.log` at the repo root.
+
+---
+
+## Pre-commit hook
+
+A simple pre-commit hook that auto-formats staged C/C++ files using the
+project's `.clang-format` rules:
+
+```bash
+./scripts/install-pre-commit.sh
+```
+
+This installs `.git/hooks/pre-commit`. Re-run after `git clone` on a fresh
+checkout.
+
+---
+
+## Memory checks (valgrind)
+
+Run `valgrind` against the integration or stress test binaries to check for
+memory leaks and other issues:
+
+```bash
+valgrind --leak-check=full ./build-debug/bin/livekit_integration_tests
+valgrind --leak-check=full ./build-debug/bin/livekit_stress_tests
+```
+
+`valgrind` is Linux-only. On macOS, use `leaks` or Instruments instead.
+
+---
+
+## API documentation (Doxygen)
+
+API reference is generated from headers using Doxygen. To rebuild locally:
+
+```bash
+./scripts/generate-docs.sh
+```
+
+Output lands under `docs/doxygen/html/`. The deployed reference is at
+[docs.livekit.io/reference/client-sdk-cpp/](https://docs.livekit.io/reference/client-sdk-cpp/).
+
+To view the generated documentation locally, open `docs/doxygen/html/index.html` in your browser.
+
+For details on the Doxygen configuration and CI pipeline, see the
+[doxygen/](doxygen/) folder.
+
+---
+
+## Development tips
+
+### Bump the pinned Rust submodule
+
+```bash
+cd client-sdk-cpp
+git fetch origin
+git switch -c try-rust-main origin/main
+
+# Sync submodule URLs and check out what origin/main pins (recursively):
+git submodule sync --recursive
+git submodule update --init --recursive --checkout
+
+# If the nested submodule under yuv-sys didn't materialize, force it:
+git -C client-sdk-rust/yuv-sys submodule sync --recursive
+git -C client-sdk-rust/yuv-sys submodule update --init --recursive --checkout
+
+# Sanity check:
+git submodule status --recursive
+```
+
+### If `yuv-sys` fails to build
+
+```bash
+cargo clean -p yuv-sys
+cargo build -p yuv-sys -vv
+```
+
+### Full clean (Rust + C++ build folders)
+
+To delete all build artifacts from both Rust and C++ folders, plus the
+local-install folder:
+
+```bash
+./build.sh clean-all
+```
diff --git a/docs/tracing.md b/docs/tracing.md
new file mode 100644
index 00000000..f74fa75c
--- /dev/null
+++ b/docs/tracing.md
@@ -0,0 +1,35 @@
+# Tracing
+
+The SDK includes built-in support for [Chromium tracing](https://www.chromium.org/developers/how-tos/trace-event-profiling-tool/),
+allowing you to capture detailed performance traces for debugging and
+optimization.
+
+## Basic usage
+
+```cpp
+#include
+
+// Start tracing to a file
+livekit::startTracing("trace.json");
+
+// ... run your application ...
+
+// Stop tracing and flush to file
+livekit::stopTracing();
+```
+
+## Filtering by category
+
+You can optionally filter which categories to trace:
+
+```cpp
+// Trace only specific categories (supports wildcards)
+livekit::startTracing("trace.json", {"livekit.*", "webrtc.*"});
+```
+
+## Viewing traces
+
+Open the generated trace file in one of these viewers:
+
+- **Chrome**: navigate to `chrome://tracing` and click "Load" to open the trace file.
+- **Perfetto**: open [ui.perfetto.dev](https://ui.perfetto.dev) and drag-drop your trace file.
diff --git a/scripts/generate-docs.sh b/scripts/generate-docs.sh
index cd373f1f..22d442a3 100755
--- a/scripts/generate-docs.sh
+++ b/scripts/generate-docs.sh
@@ -154,7 +154,7 @@ cp "$repo_root/docs/doxygen/Doxyfile" "$doxyfile_tmp"
{
echo ""
echo "# Local override generated by scripts/generate-docs.sh"
- echo "INPUT = include/livekit ${mainpage_rel} README_BUILD.md"
+ echo "INPUT = include/livekit ${mainpage_rel} docs/README.md docs/building.md docs/logging.md docs/tracing.md docs/testing.md docs/tools.md"
echo "USE_MDFILE_AS_MAINPAGE = ${mainpage_rel}"
} >>"$doxyfile_tmp"
diff --git a/scripts/install-pre-commit.sh b/scripts/install-pre-commit.sh
new file mode 100755
index 00000000..fa37da84
--- /dev/null
+++ b/scripts/install-pre-commit.sh
@@ -0,0 +1,37 @@
+#!/usr/bin/env bash
+#
+# Copyright 2026 LiveKit
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# install-pre-commit.sh -- Install a git pre-commit hook that runs
+# `scripts/clang-format.sh --fix` on staged C/C++ files. Re-stages any
+# files the formatter rewrote so the commit includes the fixes.
+
+set -euo pipefail
+
+repo_root="$(git rev-parse --show-toplevel)"
+hook_path="${repo_root}/.git/hooks/pre-commit"
+
+cat >"${hook_path}" <<'HOOK'
+#!/bin/sh
+# Auto-format staged C/C++ files using ./scripts/clang-format.sh --fix.
+files=$(git diff --cached --name-only --diff-filter=ACMR \
+ -- "*.c" "*.cc" "*.cpp" "*.cxx" "*.h" "*.hpp" "*.hxx")
+[ -z "${files}" ] && exit 0
+echo "${files}" | xargs ./scripts/clang-format.sh --fix
+echo "${files}" | xargs git add
+HOOK
+
+chmod +x "${hook_path}"
+echo "Installed pre-commit hook at ${hook_path}"