wui is a cross-platform C++/C library for creating native desktop GUIs using system webviews (Edge/WebView2 on Windows, WKWebView on macOS, WebKitGTK on Linux). It offers a minimal, portable API for embedding HTML/CSS/JS-powered UIs in your C++ or C applications.
- Cross-Platform: Windows, macOS, Linux (GTK/WebKit).
- Single header library: Optionally amalgamate to
wui_amalgamation.h. - C++ and C API: Use from either language.
- HTML/JS Asset Serving: Serve HTML, JS, and other assets from memory.
- Function Binding: Easily expose C++/C functions to JS (via
window.bindings). - Native Window Controls: Hide, show, resize, minimize/maximize windows.
- Custom Window Styling: Remove OS decorations, make fixed/resizable windows.
- Debugging: Enable/disable devtools.
- Language Bindings (WIP) will come out of the box with language bindings for GoLang/Bun/Deno/C#
This repository is not production ready, but working.
It exists primarily as a toy project to help me learn and understand the inner workings of cross-platform development aswell as webviews in general.
APIs, structure, and behavior may change at any time.
- C++17 (or C11 for C API)
- On Windows: Edge WebView2 runtime, MSVC or MinGW (with WebView2 SDK)
- On macOS: Xcode toolchain (WKWebView)
- On Linux: GTK+ 3, WebKit2GTK 4.1 (
libgtk-3-dev,libwebkit2gtk-4.1-dev)
This project uses Premake5:
# Generate build files
premake5 gmake # or premake5 vs2022 on Windows
# Build (Linux/macOS)
cd build && make wui-testapp
# Build (Windows, MinGW)
cd build && mingw32-make wui-testappOr use the provided VSCode tasks.
C++ (see src/testapp.cpp)
#include "wui.h"
int main() {
wui::allow_inspect(true); // Enable devtools
auto w = wui::create_view();
w->bind_function("hello", wui::make_binding([]() {
return "hello from C++!";
}));
w->set_html("<h1>Hi from wui!</h1><button onclick='bindings.hello().then(alert)'>Say Hi</button>");
w->show();
wui::run();
return 0;
}C (see src/testapp.c)
#include "wui.h"
#include <stdio.h>
const char* html = "<h1>Hello from C</h1>";
const char* my_callback(const char* json) {
printf("Called from JS with args: %s\n", json);
return "\"Hello from C!\"";
}
int main() {
wui_enable_debug(true);
wui_handle_t w = wui_new();
wui_set_html(w, html);
wui_bind_function(w, "hello", my_callback);
wui_os_loop();
return 0;
}| C++ API | C API |
|---|---|
wui::create_view() |
wui_new() |
view->set_html(html) |
wui_set_html(view, html) |
view->navigate(url) |
wui_navigate(view, url) |
view->bind_function("name", binding) |
wui_bind_function(view, "name", cb) |
view->set_size(w, h) |
wui_set_size(view, w, h) |
view->show(), view->hide() |
wui_show(view), wui_hide(view) |
wui::run() |
wui_os_loop() |
| ... | ... |
For more, see include/wui.h.
- In JS, call native functions via the global
bindingsobject:
bindings.hello("arg1", 42).then(result => { ... });- Bindings are defined in C++/C and exposed to JS automatically.
- Results and exceptions are marshaled via JSON.
You can serve custom assets (HTML, JS, images) from memory using the asset request callback. See wui_on_asset_requested or view->on_asset_requested.
To generate a single-header version (wui_amalgamation.h):
premake5 amalgamate.
├── include/ # Public and internal headers
├── src/ # C/C++ library and test apps
├── embed/ # Embedded asset files
├── scripts/ # Build scripts (Premake/Lua)
├── build/ # Build output (ignored)
├── premake5.lua # Build configuration
- WebView2 SDK
- Apple Docs for WKWebView
- GTK WebKit2
- Inspired by libraries like webview/webview
- Copilot for co-writing this Readme