Ultralight is a GPU-accelerated toolkit for embedding HTML in games and native apps. Lightweight and multi-platform. Developed in collaboration with leading AAA game studios.

Use the web tooling your team already knows.
Supports a wide variety of platforms and integrations, GPU and CPU.
Native bindings for DOM, events, and data. JavaScript optional.
Two bare-metal renderers designed for speed. Pick your path:
Renders directly on the GPU using platform-agnostic display lists. Supports compressed textures and in-game image compositing. Tuned for 120Hz and beyond.
Renders in pure CPU with a multithreaded SIMD pipeline. Perfect for quick integration or headless server environments.
Ultralight's pure-GPU vector renderer. Complex SVGs, animated text, strokes, and more rasterize entirely in hardware at the speed of light.
Bare-metal DOM and JavaScript bindings.
Manipulate HTML/CSS directly from C++ with the syntax you already know from JavaScript.
hud.html1<div id="hud"> 2 <p id="status">Offline</p> 3 <div class="track"> 4 <div id="hp"></div> 5 </div> 6 <button id="save">Save</button> 7</div> 8 9<style> 10 #status.online { color: lime; } 11 #hp { transition: width 0.3s; } 12</style>
hud.cpp1// Runs with JavaScript disabled, too. 2dom::Document document(view.get()); 3 4auto status = document.getElementById("status"); 5status.textContent = "Connected"; 6status.classList.add("online"); 7 8auto hp = document.getElementById("hp"); 9hp.style.width = dom::StyleValue::Pct(health); 10hp.style.backgroundColor = Color("#ff3366"); 11 12document.getElementById("save").addEventListener( 13 "click", [] { SaveGame(); });
Use data bindings to automatically sync HTML/CSS with C++ state and emit callbacks.
hud.html1<div class="hud"> 2 <h1>{{player.name}}</h1> 3 <div class="bar" ul-var-hp="player.hp"></div> 4 <p ul-if="player.poisoned">Poisoned!</p> 5 <button ul-on:click="player.heal">Heal</button> 6</div> 7 8<style> 9 .bar { 10 width: calc(var(--hp) * 1%); 11 background: hsl(calc(var(--hp) * 1.2), 70%, 45%); 12 } 13</style>
hud.cpp1struct Player { 2 std::string name = "Ava"; 3 int hp = 80; 4 bool poisoned = false; 5}; 6 7template <> struct dd::TypeTraits<Player> { 8 static constexpr auto schema = dd::Schema( 9 dd::Reflect<Player>(), dd::Action("heal")); 10}; 11 12dd::Binding binding = ctx.Bind("player", player); 13binding.OnAction<"heal">([&] { player.hp = 100; }); 14ctx.Sync(); // once per frame
Expose native C++ data and callbacks to JavaScript with an expressive and type-safe API.
app.html1<script type="module"> 2 console.log(app.version); // "2.1.0" 3 4 // Resolves once a worker thread reads the file. 5 const doc = await app.open("notes.md"); 6 document.title = doc.title; 7 editor.value = doc.body; 8 9 app.on("synced", (count) => showBadge(count)); 10 11 app.open(42); // rejects with a TypeError 12</script>
app.cpp1struct Doc { std::string title, body; }; 2 3js::API app("app"); 4app["version"] = "2.1.0"; 5app["open"] = [](std::string path) -> js::Task<Doc> { 6 co_return co_await js::RunOnWorker( 7 [path] { return LoadDoc(path); }); 8}; 9 10if (app.AttachTo(view.get())) 11 view->LoadURL("file:///app.html"); 12 13app.Emit("synced", 3); // from any thread
A stripped-down, single-process, platform-agnostic port of WebKit designed for embedding.
Ultralight uses significantly less RAM than other HTML solutions and is designed for the tightest resource budgets.
Everything runs inside your application's process, so memory stays predictable and small.
Write once. Display anywhere.
Identical rendering on every platform you ship: Windows, macOS, Linux, PlayStation, Xbox, ARM64 devices, and more. One UI build serves desktop, console, and embedded.
HTML5 media playback with VP9 video and Opus audio, supported on both renderers.
Run trailers, cutscenes, and ambient motion directly inside your UI. The GPU renderer plays 4K comfortably.
Proven in AAA productions. Integrate with your engine's renderer and composite UI over your scene with full transparency.
Game integration guideLightweight desktop apps with native look and feel, or fully custom chrome. Pin a version and ship the same UI everywhere.
Native app guideFor embedded devices where every CPU cycle counts. Our bare-metal DOM API was designed for the tightest resource budgets.
Read the docs
We are the same team behind Awesomium, the first embedded web framework for games and desktop apps (used by EA, Square Enix, and many more).
In 2015, we made the bold decision to move off Chromium and rewrite the library with a focus on performance, portability, and ease of use. The result is Ultralight, refined ever since with leading game studios and tech companies.
Ultralight currently supports the following platforms:
Ultralight is a custom fork of WebKit supporting most of the modern web spec. 2.0 adds HTML5 media playback and hardware-accelerated vector graphics.
We recommend trying the Browser sample in the SDK to get an idea of what Ultralight is capable of today.
Yes. Ultralight 2.0 adds HTML5 media playback with VP9 video and Opus audio, up to 4K.
Yep! Ultralight uses the same JavaScript engine as WebKit/Safari, so modern frameworks run as-is.
Yes. The native DOM, Events, and data-binding APIs run interface logic entirely in native code, with no JavaScript VM in the loop. Re-enable JavaScript whenever you want it.
Any engine that can display a dynamic texture works: render via the CPU to an offscreen bitmap, or integrate the GPU renderer directly.
The ImageSource API also lets your engine's textures appear inside page content. See the game integration guide in the docs for more.
We maintain official APIs for C and modern C++.
Several awesome members of our community maintain bindings for C#, Java, Rust, and Go on top of our portable C API.
A portion of our WebCore source code is available under LGPL on GitHub.
Full source access is available with an Enterprise license. Contact sales.
Get the SDK and explore its capabilities today.