Saucer
๐ธ A modern, cross-platform C++ webview library
Install / Use
/learn @saucer/SaucerREADME
<div align="center"> <img src="https://github.com/saucer/saucer.github.io/blob/v7/src/assets/preview.png?raw=true" width="600" />
Documentation
The documentation can be found here.
Examples
Examples can be found here.
Getting started
Learn how to create your first saucer app here.
Community
Mirrors
Saucer is available on: GitHub, Codeberg
</div>๐ฝ Introduction
Saucer is a modern C++ webview library that allows you to build cross-platform desktop applications with ease.
It supports all three major desktop operating systems (Windows, Linux, MacOS) and has several backend implementations.
๐ธ Features
-
โ๏ธ FOSS
Licensed under MIT!
-
๐ชถ Lightweight
By using the operating systems native web renderer[^1], it is possible to create binaries as small as ~250KB
-
๐ Seamless C++ / JavaScript interoperability
Convenient API (powered by reflection) to evaluate JavaScript Code or expose C++ functions to JavaScript!
> Example -
๐พ Feature-Rich
Supports custom schemes, script injection, favicons, and much more!
-
ใ๏ธ Unicode Support
-
๐ Coroutine Support
See Code Example below!
-
๐ฆ Supports Embedding Frontend into binary
Ship a contained binary with ease!
> Documentation -
๐ฆบ Thread-Safe
-
๐งจ No Exceptions[^3]
Compiles with
-fno-exceptions! -
๐ No RTTI
Compiles with
-fno-rtti! -
๐ช Built-in support for frame-less windows and transparency
Supports
data-webviewattributes to allow effortless custom title-bars.
> Documentation -
๐งฐ Customizable
Exposes platform specific implementations, making it possible to tweak the library to your hearts content!
> DocumentationSaucer also provides official extensions in the form of modules:
| Module | Description | | --------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | | saucer/desktop | ๐ File-Picker, Mouse-Position retrieval and URI-Launch support <br> > Example | | saucer/pdf | ๐ Export current page as PDF <br> > Example | | saucer/loop | ๐ "Legacy"[^2] loop implementation <br> > Example |
-
๐ป Supports various backends
<table> <tr> <th>Platform</th> <th colspan="2">Backends</th> </tr> <tr> <td><b>Windows</b></td> <td>Win32 & WebView2</td> <td rowspan="3">Qt + QWebEngine</td> </tr> <tr> <td><b>Linux</b></td> <td>GTK4 & WebKitGtk</td> </tr> <tr> <td><b>MacOS</b></td> <td>Cocoa & WKWebView</td> </tr> </table> -
๐๏ธ Bindings
Saucer also exposes a C-Interface, thus making it possible to write bindings for it in your favorite language!
| Language | Repository | | -------- | ------------------------------------ | | Java | https://github.com/saucer/saucer4j | | PHP | https://github.com/boson-php | | Rust | https://github.com/skjsjhb/saucers |
Please note: All bindings are community maintained!
-
๐ฆฅ ... and more!
[^1]: ... or a commonly used one
[^2]: For lack of a better word
[^3]: Saucer catches exceptions thrown in exposed functions - if not compiled with -fno-exceptions - by default. This can be explicitly disabled via set(saucer_exceptions OFF)
๐ฆ Installation
<table> <tr> <th> <a href="https://github.com/cpm-cmake/CPM.cmake" target="_blank">CPM</a> </th> <th> FetchContent </th> </tr> <tr> <td>CPMFindPackage(
NAME saucer
VERSION 8.0.5
GIT_REPOSITORY "https://github.com/saucer/saucer"
)
</td>
<td>
FetchContent_Declare(
saucer
GIT_TAG v8.0.5
GIT_REPOSITORY "https://github.com/saucer/saucer"
)
FetchContent_MakeAvailable(saucer)
</td>
</tr>
<tr>
<td colspan="2">
Note: Replace <target> with your respective target:
target_link_libraries(<target> saucer::saucer)
</td>
</tr>
</table>
See the documentation for more information!
โ๏ธ Code Example
#include <print>
#include <saucer/smartview.hpp>
coco::stray start(saucer::application *app)
{
auto window = saucer::window::create(app).value();
auto webview = saucer::smartview::create({.window = window});
window->set_title("Hello World!");
window->set_size({.w = 800, .h = 600});
webview->expose("add_demo", [&](double a, double b) -> coco::task<double>
{
co_return a + b + *co_await webview->evaluate<double>("Math.random()");
});
auto index = saucer::url::from("index.html");
if (!index.has_value())
{
co_return std::println("{}", index.error());
}
webview->set_url(index.value());
window->show();
co_await app->finish();
}
int main()
{
return saucer::application::create({.id = "example"})->run(start);
}
๐ See more examples!
๐ต Buy me a tea
Saucer is a passion project and I develop it in my free-time. If you'd like to support me, consider sponsoring my tea-addiction ๐ซ
๐ Who's using saucer?
<div align="center">| <img src="https://casterlabs.co/images/product/caffeinated/multi-chat.png" width="1000" /> | <img src="https://raw.githubusercontent.com/SamsidParty/TopNotify/main/Docs/Screenshot3.png" width="1250" /> | | :----------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------: | | Casterlabs - Caffeinated | TopNotify | | (Built on saucer4j) | (Built on their C# Saucer Bindings "IgniteView") |
</div> <br/>โญ Star History
<a href="https://notbyai.fyi/" target="_blank"> <img align="right" src="https://raw.githubusercontent.com/saucer/saucer.github.io/refs/heads/v7/src/assets/badge.svg" /> </a>Saucer is 100% human written. No AI-Tools were used in the development process.
