PyWebWinUI3 is a Windows desktop UI framework that combines:
The goal is to make desktop apps feel like WinUI3-style apps while still being driven from Python.
PyWebWinUI3 lets you:
At runtime, Python owns the application state, Qt hosts the window and WebEngine, and the Svelte app renders the page tree received from Python.
PyWebWinUI3 is currently aimed at Windows.
Runtime dependencies:
PySide6pywin32pip install PyWebWinUI3
from pywebwinui3.core import MainWindow
from pywebwinui3.type import Status
app = MainWindow("PyWebWinUI3")
app.addSettings("Settings.xaml")
app.addPage("Dashboard.xaml")
app.addPage("test.xaml")
app.values["test_input"] = "Hello, world"
app.values["test_switch"] = False
@app.onValueChange("test_noticeSample")
def show_notice(*_):
app.notice(Status.Attention, "Title", "This is a sample notice")
app.start()
<Page path="settings" icon="" name="Settings" title="Settings">
<Box>
<Horizontal>
<Text>App theme</Text>
<Space />
<Select value="system_theme">
<Option value="dark">Dark</Option>
<Option value="light">Light</Option>
<Option value="system">Use system setting</Option>
</Select>
</Horizontal>
</Box>
</Page>
MainWindowpywebwinui3.core.MainWindow is the main entry point.
Important methods:
addPage(...)addSettings(...)start(debug=False, min_width=900, min_height=600)notice(level, title, description, item=None)pin(state)syncValue(key, value)valuesapp.values is the shared state dictionary between Python and the frontend.
Typical usage:
app.values["user_name"] = "Haruna"
app.values["is_enabled"] = True
app.values["progress"] = 50
The frontend reads these values directly, and user input writes back into the same store.
Built-in system values include keys such as:
system_titlesystem_iconsystem_themesystem_theme_resolvedsystem_accentsystem_pagessystem_settingssystem_noficationsystem_pinsystem_window_widthsystem_window_heightMainWindow exposes decorator-style event hooks:
@app.onValueChange(key)@app.onAccentColorChange()@app.onThemeChange()@app.onSetup()@app.onExit()Example:
@app.onValueChange("user_name")
def on_user_name_change(*_):
print(app.values["user_name"])
Use app.notice(...) to push InfoBar-style messages into the frontend.
from pywebwinui3.type import Status
app.notice(Status.Success, "Saved", "Settings were saved successfully")
Status values:
Status.AttentionStatus.SuccessStatus.CautionStatus.CriticalStatus.NeutralPages are loaded into a JSON tree and rendered by the frontend.
Common tags currently implemented:
PageBoxHorizontalVerticalTextButtonInputSliderSwitchCheckRadioSelectOptionImageWebviewProgressbarLineSpaceExpenderIfMatchRepeatPyWebWinUI3 supports two main binding styles:
value="test_input"{user_name}The frontend compiles and caches formatted expressions, while Python remains the source of truth for state.
Path-like targets such as nested array access are also handled by the runtime value system when used by supported controls.
Relative resource paths are resolved from the Python caller's directory first, then from the packaged frontend bundle directory.
This lets you write things like:
addPage("Dashboard.xaml")External URLs such as https://... and file://... are passed through as-is.
The desktop shell is implemented in Qt and provides:
PyWebWinUI3/
├─ pywebwinui3/
│ ├─ core.py # public Python API
│ ├─ qt.py # Qt shell and bridge
│ ├─ util.py # XAML loader, sync dict, accent watcher
│ ├─ event.py # event system
│ ├─ type.py # status and theme resource constants
│ └─ web/ # built frontend bundle shipped to users
├─ frontend/ # Svelte source
├─ example/ # sample application and XAML pages
└─ setup.py
If you are only using the package, you do not need to build the frontend manually.
If you are working on the framework itself:
pywebwinui3/frontend/pywebwinui3/web/See:
example/example.pyexample/Settings.xamlexample/Dashboard.xamlexample/Test.xamlApache-2.0