Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

PyWinUI

Build native WinUI 3 (Windows App SDK) desktop applications in idiomatic Python.

Not a themed look-alike and not a reimplementation — these are real WinUI 3 controls, wrapped so that you never have to touch WinRT unless you want to.

import pywinui as ui


class CounterApp(ui.App):
    def build(self):
        count = ui.TextBlock("0", font_size=32)

        def bump(sender, args):
            count.text = str(int(count.text) + 1)

        return ui.Window(
            title="PyWinUI Counter",
            content=ui.StackPanel(
                spacing=12, padding=24,
                children=[
                    ui.TextBlock("Counter", font_size=20),
                    count,
                    ui.Button("Increment", on_click=bump),
                ],
            ),
        )


CounterApp().run()

Status: early alpha. The architecture is verified end-to-end against the real bindings on Windows 11, but only five controls are wrapped so far. The API may change. See Current scope before depending on it.

Why now

The WinUI 3 projections for Python (PyWinRT) only landed in March 2025. Before that, a Python WinUI 3 app meant hand-rolling raw WinRT. The bindings now exist and work; PyWinUI is the ergonomics layer on top of them.

Requirements

  • Windows 10/11 with the Windows App Runtime
  • python.org Python 3.10+ — not the Microsoft Store build, which is a packaged app and fails the runtime bootstrap with ERROR_NOT_SUPPORTED

Install

pip install pywinui

The winui3-* dependencies are Windows-only and install automatically there. On other platforms the package still installs and imports (the native layer is loaded lazily), so the test suite and editor tooling work anywhere — but anything that realizes a control needs Windows.

Two ways to build a tree

Both are first-class and they compose.

# Flutter style — the tree is a value. Best for reusable components.
ui.StackPanel(children=[ui.TextBlock("a"), ui.TextBlock("b")])

# With style — handles loops, conditionals and local references far better.
with ui.StackPanel() as panel:
    ui.TextBlock("Items")
    for name in items:
        ui.Button(name, on_click=make_handler(name))

Async without the ceremony

Handlers may be async def. They're scheduled off the UI thread automatically, WinRT async operations are awaited like any coroutine, and writes back to widgets are marshalled onto the UI thread for you.

async def read_file(sender, args):
    status.text = "Reading..."
    file = await StorageFile.get_file_from_path_async(path)
    text = await FileIO.read_text_async(file)      # real WinRT I/O
    status.text = f"{len(text)} chars"             # marshalled back to the UI

Failures arrive as ordinary Python exceptions — a missing path raises FileNotFoundError.

The escape hatch

The curated surface covers the common path with type hints, validation and value conversions. Anything not wrapped still forwards by name, and widget.native gives you the raw WinUI control:

btn = ui.Button("Save")
btn.native.background = some_brush    # raw WinUI, fully supported

Current scope

Working Not yet
TextBlock, TextBox, Button, StackPanel, Grid, Window The other ~100 WinUI controls
Both tree-building styles, attach/detach Data binding, styles, resource dictionaries
async def handlers, awaiting WinRT ops Control templates, virtualized lists
Off-thread writes auto-marshalled Off-thread reads (wrap in run_on_ui)
padding/margin, visible, content boxing Grid.Row/Grid.Column attached properties
Running from a Python environment Packaging a double-clickable app (MSIX)

Packaging is unproven. Shipping an app to end users means bundling Python and the Windows App Runtime, likely as MSIX, and that path has not been prototyped. Today this is a library for developers who already have Python installed.

Troubleshooting

DLL load failed ... The filename or extension is too long — your virtual environment path is too deep. The winui3 extension modules have very long file names (_winui3_microsoft_windows_applicationmodel_dynamicdependency_bootstrap), and a nested venv can push them past Windows' 260-character MAX_PATH. Use a shorter path, or enable long paths.

ERROR_NOT_SUPPORTED during bootstrap — you're on the Microsoft Store build of Python, which is itself a packaged app. Use the python.org installer.

Examples

pip install -e ".[examples,dev]"
python examples/counter.py
python examples/async_file_read.py

Tests

pytest

The suite runs anywhere — no Windows required. It swaps in a fake native layer to lock down the tree model, both building styles, attach/detach, property forwarding, value conversions and thread marshalling. What it deliberately cannot cover is the binding boundary itself; that is verified by running the examples on Windows.

License

MIT

Metadata

Release files for pywinui 0.1.0a1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pywinui 0.1.0a1
File Size Uploaded
pywinui-0.1.0a1.tar.gz 21.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pywinui 0.1.0a1
File Interpreter ABI Platform
pywinui-0.1.0a1-py3-none-any.whl Python 3 none any Details

Total release size: 34.9 kB

Release files / pywinui-0.1.0a1.tar.gz

Download URL pywinui-0.1.0a1.tar.gz
Size 21.8 kB
Tags Source
SHA-256 checksum
How to use checksums
8fd33c5e17a9dd44e6c22eebca6343d5b818fc67c7b98687891085673baca95f
BLAKE2b-256 checksum
How to use checksums
e353e7201b0911f5e5d650ea92e275589f662cdd67e2fc1e41bbe7987260db24
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.11

Release files / pywinui-0.1.0a1-py3-none-any.whl

Download URL pywinui-0.1.0a1-py3-none-any.whl
Size 13.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6d87ca6a574f13aa87a9eeb8a02365b0783af5480bc965f25a5d2c62e719254f
BLAKE2b-256 checksum
How to use checksums
32d1c0709b6ebb8261ffb6c1082239963cdf2070dfe8cf646f187283e91bfb49
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.11

Release history Release notifications | RSS feed

This release

0.1.0a1 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page