You can link Ultralight to your project using CMake or configure your build system manually.

The CMake package configures includes, link targets, and runtime file staging automatically. If you use another build system you can set includes and linker settings directly.

## Link via CMake

The SDK provides CMake configuration files that import library targets and stage runtime dependencies beside the compiled binary.

### Basic Configuration

To link Ultralight in CMake, find the package, link `AppCore`, and copy the runtime dependencies.

```cmake
cmake_minimum_required(VERSION 3.15.0)
project(MyApp LANGUAGES C CXX)

find_package(Ultralight REQUIRED)

add_executable(MyApp WIN32 MACOSX_BUNDLE main.cpp)
target_link_libraries(MyApp PRIVATE Ultralight::AppCore)

# Copy the shared libraries and resources next to the executable.
ultralight_copy_runtime_files(MyApp)

if (CMAKE_SYSTEM_NAME MATCHES "Windows")
  # Use main instead of WinMain.
  set_target_properties(MyApp PROPERTIES LINK_FLAGS "/ENTRY:mainCRTStartup")
endif ()
```

Setting up the build requires three steps:

1. Call `find_package(Ultralight REQUIRED)` to import the library targets.
2. Link `Ultralight::AppCore` (or `Ultralight::Ultralight`) to your executable target.
3. Call `ultralight_copy_runtime_files()` to copy the shared libraries and resources next to the compiled binary.

> 📘 Linking Without AppCore
>
> `AppCore` is optional— you only need it when calling `App::Create()` or using the default `Platform` implementations. If you create the renderer with `Renderer::Create()` and provide custom handlers, link `Ultralight::Ultralight` instead and do not ship the `AppCore` library.

### Locate the SDK

Pass the SDK root path to CMake using `CMAKE_PREFIX_PATH` when generating build files.

```shell
cmake -B build -DCMAKE_PREFIX_PATH=C:/ultralight-sdk
```

You can also point directly to the package folder with `-DUltralight_DIR=<path>/lib/cmake/Ultralight`.

### Imported Targets

The CMake package defines four layered targets— linking any target automatically pulls in each layer beneath it.

Most applications link `Ultralight::AppCore`, which includes every required target.

| Target | Contents |
| :--- | :--- |
| `Ultralight::AppCore` | Optional application runtime (`App`, `Window`) and platform integration code. |
| `Ultralight::Ultralight` | Main engine and compositor (`Renderer`, `View`, `Session`). |
| `Ultralight::WebCore` | HTML layout engine and the JavaScriptCore C API (`JS*`). |
| `Ultralight::UltralightCore` | Low-level drawing primitives and the `Platform` interface singleton. |

### Platform Reference Sources

`AppCore` includes prebuilt reference platform handlers for GPU drivers, font loaders, clipboards, file systems, CPU window surfaces (Windows and Linux only), a file logger, and audio outputs. Audio outputs require the Pro edition or higher (see [Editions and Feature Macros](/docs/2.0/editions-and-feature-macros)).

If you create the renderer with `Renderer::Create()` or need custom handler modifications, you can build the reference implementations from source instead.

To add the reference handlers to a CMake project, include the platform directory and link `Ultralight::Platform`.

```cmake
add_subdirectory(${ULTRALIGHT_PLATFORM_DIR} platform)
target_link_libraries(MyApp PRIVATE Ultralight::Platform)
```

## Link Manually

To configure another build system without CMake, add the SDK header directory, link the necessary libraries, and stage runtime files beside the compiled executable.

### Compiler Settings and Include Paths

C++ code requires a compiler configured for C++20 or later. C applications require C17 or later.

Add the SDK's `include/` directory to the header search paths. This folder contains the `Ultralight/`, `AppCore/`, and `JavaScriptCore/` headers.

### Link Libraries

Applications using `AppCore` link `AppCore`, `Ultralight`, and `UltralightCore`. If you create the renderer directly with `Renderer::Create()` and provide custom platform handlers, link `Ultralight` and `UltralightCore` instead.

Linking `WebCore` is optional— you only need it when calling the JavaScriptCore C API directly (the `JS*` functions from `<JavaScriptCore/...>`). The JavaScript API (`js::`) is part of `Ultralight`, so using it doesn't require linking `WebCore`.

| Platform | Libraries | Optional |
| :--- | :--- | :--- |
| Windows | `AppCore.lib`, `Ultralight.lib`, `UltralightCore.lib` from `lib/` | `WebCore.lib` |
| macOS | `libAppCore.dylib`, `libUltralight.dylib`, `libUltralightCore.dylib` from `bin/` | `libWebCore.dylib` |
| Linux | `libAppCore.so`, `libUltralight.so`, `libUltralightCore.so` from `bin/` | `libWebCore.so` |

### Stage Runtime Files

An application requires its runtime dependencies staged beside the compiled executable. The shared libraries sit in the same directory as the binary, while runtime resources sit inside an `assets/` folder beside it.

#### Shared Libraries

Runtime requirements differ from link time. Each shared library loads the layers beneath it, so every layer the application uses must sit beside the compiled binary. This includes `WebCore`— `Ultralight` loads it at runtime even when you didn't link against it.

Copy the shared libraries from the SDK's `bin/` directory (`.dll` on Windows, `.dylib` on macOS, or `.so` on Linux):

- **Applications using `App::Create()`** — copy all four libraries: `AppCore`, `Ultralight`, `WebCore`, and `UltralightCore`.
- **Applications using `Renderer::Create()`** — copy `Ultralight`, `WebCore`, and `UltralightCore`. Leave `AppCore` out.

#### Resources and the Web Inspector

Copy the SDK's `resources/` folder to `assets/resources/` beside the compiled executable.

If you open the Web Inspector, also copy the SDK's `inspector/` folder to `assets/inspector/`.

### Set Run-Time Search Paths

On Windows, the OS searches the folder containing the executable for shared libraries automatically.

On macOS, the shared libraries use `@rpath` install names. Set the executable's rpath to `@executable_path/` so the dynamic linker finds them beside the binary.

On Linux, set the executable's rpath to `$ORIGIN` (or configure `LD_LIBRARY_PATH`) so the dynamic linker resolves libraries from the application directory.

### Linux System Dependencies

The prebuilt Linux libraries require glibc 2.31 or newer.

When linking `libAppCore.so`, the host system also requires `libX11`, `libX11-xcb`, `libxcb`, `libxcb-present`, and `libfontconfig`. GTK 3 is loaded on demand only when your app displays a message box.

## Package for Distribution

For platform-specific bundling rules, install scripts, and macOS app bundle layout, see [Shipping Your App](/docs/2.0/shipping-your-app).
