WinRT in the Python UI Ecosystem: Adoption and the Value of dynwinrt
July 21, 2026 ยท View on GitHub
Research snapshot: July 20, 2026
What this research asks
Is there real user value in adding Python support to dynwinrt?
Yes, but the value is not in creating another Python UI framework.
Python developers already build user interfaces with Qt, Tkinter, wxPython, Kivy, and pywebview. Those applications still need Windows-specific features such as notifications, media controls, OCR, Wi-Fi, Bluetooth, sensors, and system colors. Today, they primarily access those APIs through the static pywinrt projection.
Public data shows that:
- Mainstream Python UI frameworks have hundreds or thousands of public dependent repositories.
winrt-runtimehas about 3.36 million cumulative downloads and approximately 405 downstream PyPI packages.- Real Qt, Tkinter, wxPython, Kivy, and pywebview projects directly call pywinrt.
- UI projects represent only part of pywinrt adoption. Non-UI libraries for BLE, notifications, and OCR are more common.
The audience for dynwinrt Python support is therefore developers who already have a UI framework but still need Windows APIs. dynwinrt would provide the Windows API access layer, not replace the UI framework.
Terminology
| Term | Meaning in this document |
|---|---|
| UI framework | Provides windows, controls, and UI events. Examples include PyQt, PySide, Tkinter, and wxPython. |
| WinRT | A set of Windows system APIs for capabilities such as notifications, media, OCR, Bluetooth, and sensors. |
| Python projection | Converts WinRT COM/ABI interfaces into ordinary Python classes, methods, and events. |
| pywinrt | The current active static Python projection. Each WinRT namespace is generated and compiled into a wheel ahead of time. |
| dynwinrt | Generates lightweight Python wrappers and invokes the WinRT ABI through a shared native runtime. |
"Python UI framework" describes the API used by Python developers, not necessarily the language used to implement the framework. PyQt and PySide wrap the C++ Qt framework; Tkinter wraps Tcl/Tk; wxPython wraps C++ wxWidgets; Dear PyGui wraps a C++ rendering core; and Kivy combines Python, Cython, and native graphics code. customtkinter is mostly Python, but it is built on Tkinter and therefore still uses Tcl/Tk underneath.
The UI framework and the WinRT projection solve different problems:
PyQt / Tkinter / wxPython Renders the user interface
|
| Python calls
v
pywinrt or dynwinrt Exposes Windows APIs to Python
|
v
Windows Runtime Provides notifications, media, OCR, BLE, etc.
What "directly using pywinrt" means
Direct use means that application source code imports and calls
winrt.windows.*. It does not merely mean that pywinrt appears somewhere in
the dependency tree.
For example, the Qt status bar application
YASB reads Windows system colors directly in
system_colors.py:
import winrt.windows.ui.viewmanagement as viewmanagement
settings = viewmanagement.UISettings()
accent = settings.get_color_value(viewmanagement.UIColorType.ACCENT)
token = settings.add_color_values_changed(on_color_changed)
It also manages Windows system media sessions directly in
media.py:
manager = await SessionManager.request_async()
sessions = manager.get_sessions()
properties = await session.try_get_media_properties_async()
await session.try_toggle_play_pause_async()
The call path is:
YASB PyQt6 code
-> Python classes generated by pywinrt
-> WinRT COM ABI
-> Windows system APIs
Qt still owns the UI, while pywinrt provides access to Windows APIs. YASB uses
qasync, Qt signals, and call_soon_threadsafe() to connect WinRT asynchronous
operations and events to the Qt event loop.
This differs from an indirect dependency. For example, an application may
depend on the BLE library bleak, which uses pywinrt on Windows, without the
application itself importing winrt.windows.*.
How large are the mainstream Python UI frameworks?
The "public dependent repositories" below come from ecosyste.ms. The service only counts indexed public repositories whose dependency manifests declare the package, so these values are lower bounds rather than total user counts.
| UI framework | Public dependent repositories | Typical use |
|---|---|---|
| PyQt5 | 2,667 | Mature cross-platform desktop applications |
| Kivy / KivyMD | 709 | Cross-platform and touch-oriented applications |
| customtkinter | 549 | Lightweight Windows utilities |
| PySide6 | 440 | Official Qt binding for Python |
| wxPython | 428 | Traditional desktop and accessibility applications |
| Dear PyGui | 391 | Tools, visualization, and custom rendering |
| pywebview | 242 | HTML/CSS interfaces with Python backends |
| PyQt6 | 221 | Qt 6 desktop applications |
| Flet | 201 | Flutter-based Python UI |
| Toga | 43 | BeeWare UI using native controls |
Tkinter normally ships with Python. A project can simply write
import tkinter without declaring an installable package in
requirements.txt or pyproject.toml, so dependency manifests cannot provide
a comparable repository count. GitHub Code Search finds approximately 36,584
files containing import tkinter and 80,636 files containing from tkinter.
These are file counts, not project counts, but they show that Tkinter is widely
used.
How many UI projects use pywinrt?
No data source can count every public and private project precisely. This research therefore reports two values:
- Source candidates: repositories found by searching for a Python file that
contains both the UI framework and
winrt.windows, after excluding build scripts, generated code, and vendored dependencies. - Manually verified: repositories whose source code was reviewed and confirmed to call an actual Windows API through pywinrt.
| UI framework | Source candidates | Manually verified lower bound |
|---|---|---|
| PyQt5 | 13 | At least 2 |
| PyQt6 | 19 | At least 2 |
| PySide6 | 25 | At least 1 |
| Tkinter / customtkinter | 47 | At least 9 |
| wxPython | 3 | 3 |
| Kivy / KivyMD | 2 | 2 |
| pywebview | 5 | At least 1 |
| Flet | 0 | 0 |
| Toga | 0 | 0 |
| Dear PyGui | 0 | 0 |
These numbers should be interpreted carefully:
- They prove that real demand exists, but they are not market-share figures.
- Projects are missed when their UI code and WinRT code live in different files.
- Private projects do not appear in GitHub search results.
- Qt has the strongest project evidence: YASB is a substantial application that uses WinRT across several user-facing features.
- Tkinter and customtkinter have more verified projects, but most are small or medium-sized Windows utilities.
- No verified Flet, Toga, or Dear PyGui examples were found. This means only that this research did not find one, not that none exist.
Verified real-world projects
| Project | UI framework | Windows capabilities | Integration approach |
|---|---|---|---|
| YASB | PyQt6 | System colors, media, Wi-Fi, notifications, Clipboard, packages | Imports pywinrt directly; uses qasync and Qt signals |
| Bookworm | wxPython | OneCore TTS, OCR, SoftwareBitmap | Calls WinRT on worker threads and updates the UI through wx.CallAfter() |
| Luminalium | PySide6 | Windows notifications | Creates ToastNotification directly from the Qt application |
| GhostPlayer | customtkinter | System media sessions and thumbnails | Calls WinRT on a dedicated asyncio thread and updates the UI through after() |
| nvda-browser-nav | wxPython / NVDA | Clipboard History | Calls pywinrt directly from an add-on |
| Win-Kivy-Music-Player | Kivy | Storage and media APIs | Runs WinRT asynchronous operations inside a Kivy application |
| SereneSudoku | Kivy | Microsoft Store APIs | Queries the Store directly from the game |
| spankurlaptop | pywebview | Accelerometer | Reads the sensor in the Python backend and displays the UI in a WebView |
pywinrt also provides two important samples:
- Tkinter + Composition hosts Windows Composition content in a Tk window.
- Python WinUI 3 bootstraps the Windows App SDK, loads XAML, and runs the WinUI DispatcherQueue from Python.
These projects demonstrate two distinct patterns:
- Most developers retain their existing UI framework and use WinRT only as a Windows capability layer.
- Python can directly host Composition or WinUI 3, but the visible user base for this approach is much smaller.
How widely is pywinrt used?
Downloads
The following data comes from pepy.tech. Daily averages cover July 1-19, 2026.
| Package | Cumulative downloads | July 2026 daily average | Interpretation |
|---|---|---|---|
winrt-runtime | 3,356,437 | About 12,462 | Shared runtime for the current modular pywinrt packages |
winsdk | 776,418 | About 1,951 | Archived monolithic projection that retains a long tail of users |
winrt | 227,767 | About 96 | Microsoft's original projection |
winui3-Microsoft.UI.Xaml | 22,497 | Tens per day | Core XAML package for Python WinUI 3 |
Downloads are not unique users:
- CI jobs, mirrors, and repeated installations inflate download counts.
- Libraries such as
bleakinstall pywinrt indirectly for many users. - Modular pywinrt contains many namespace packages whose downloads cannot be added together.
In addition to download counts, ecosyste.ms indexes approximately 405
downstream PyPI packages that depend on winrt-runtime. GitHub Code Search
finds 1,454 files containing import winrt.windows and 1,298 files containing
from winrt.windows.
These data points do not provide an exact user count, but together they show that calling WinRT from Python is not merely an experimental niche.
Why winrt, winsdk, and pywinrt all exist
| Generation | Status | Main characteristics |
|---|---|---|
Microsoft winrt | Discontinued after 2021 | Covers only CPython 3.7-3.9 and x86/x64 |
Community winsdk | Archived | Monolithic package supporting CPython 3.8-3.12 and ARM64 |
Current pywinrt | Active solution | One winrt-* wheel per namespace; supports CPython 3.9-3.14 and x86/x64/ARM64 |
The continued presence of all three generations shows both sustained demand and the maintenance burden of a static projection. It must track:
- Python minor versions.
- x86, x64, and ARM64.
- Windows SDK and Windows App SDK releases.
- Native wheels for every namespace.
What problem can dynwinrt solve?
pywinrt demonstrates that a static projection can support production applications. The value of dynwinrt is not to invalidate pywinrt, but to reduce a different set of costs.
Consider a new Windows API or an application that needs to consume a company's
own custom.winmd.
With a static projection
A C++ extension normally has to be generated from the WinMD, then compiled, packaged, and published as native wheels for each Python version and CPU architecture. Users must wait for the corresponding package to be released.
With dynwinrt
The dynwinrt code generator produces Python wrappers and type information from the WinMD, while every API reuses the same general-purpose native runtime. As long as the runtime supports the required ABI types, a new API or custom WinMD does not require another purpose-built native extension.
| Problem | Static pywinrt | dynwinrt approach |
|---|---|---|
| Existing Windows API | Install the runtime and relevant namespace wheels | Generate a Python package that reuses the shared runtime |
| New SDK API | Wait for or build a new native wheel | Regenerate wrappers from the new WinMD |
| Custom WinMD | Build and maintain a dedicated native projection | Use the same code generator and runtime |
| Python and JavaScript | Maintain separate projection and runtime implementations | Share the Rust ABI core |
| UI framework | Framework-independent | Also framework-independent |
| Current maturity | Production users and broad API coverage | Python support is still evolving; coverage depends on the runtime |
For an existing Python UI application, the practical value is:
- Keeping PyQt, Tkinter, wxPython, or another existing UI choice.
- Reaching new Windows SDK APIs and custom WinRT components sooner.
- Reducing the number of namespace-specific native artifacts that must be compiled and published.
- Sharing ABI implementations for arrays, structs, delegates, async operations, and generics between JavaScript and Python.
- Generating idiomatic, typed Python APIs.
The target audience is not developers looking to replace their UI framework. It is developers who already have a Python application and need easier access to Windows capabilities.
Can dynwinrt work with different UI frameworks?
For data-oriented APIs such as notifications, media, OCR, Bluetooth, and sensors, the common pattern is to call WinRT from a worker thread or asyncio task and marshal the result back to the UI thread. The real projects above have already validated this pattern.
| UI framework | Verified integration pattern |
|---|---|
| PyQt / PySide | qasync, Qt signals, and call_soon_threadsafe() |
| Tkinter / customtkinter | Background asyncio thread and after() |
| wxPython | Worker thread and wx.CallAfter() |
| Kivy | asyncio or an application-owned worker thread |
| pywebview | Python worker thread and JavaScript bridge |
| WinUI 3 | STA UI thread and DispatcherQueue |
UI-bound WinRT APIs are more complex because they require:
- Initializing WinRT with the correct apartment model on the calling thread. An apartment defines how WinRT expects that thread to handle concurrency.
- Keeping the STA UI thread processing Windows messages or a DispatcherQueue.
- Avoiding a blocking
.wait()that would freeze the UI thread.
This is not specific to one UI framework. Qt, Tk, wx, and WinUI each have their own event loop, and the projection must correctly integrate WinRT asynchronous operations and events with it.
Conclusions
- The Python UI ecosystem is already large; developers do not need dynwinrt to provide another UI framework.
- Real Qt, Tk, wx, Kivy, and pywebview projects call WinRT to add Windows-specific capabilities.
winrt-runtimedownloads and downstream packages demonstrate broader Python demand for WinRT, but they are not a count of Python WinUI users.- The number of publicly verified UI + pywinrt projects is modest, but they include mature Qt applications, accessibility software, small Windows utilities, media applications, and sensor applications.
- The value of dynwinrt is a more flexible Windows API projection for these existing Python applications, particularly for new SDKs, custom WinMD, and a runtime shared across languages.
- This research demonstrates user demand and technical feasibility. It does not claim that the current dynwinrt Python projection already covers every WinRT API or every UI-thread scenario.
Methodology
- The ecosyste.ms
dependent_repos_countis the number of indexed public repositories whose dependency manifests declare the package. - The GitHub UI overlap search required the same Python file to contain both
winrt.windowsand the UI framework name, then deduplicated results by repository. - "Source candidates" exclude
.specfiles, build scripts, generated stubs, and vendored dependencies. - "Manually verified" means that source review confirmed an actual WinRT method, property, or event call.
- The search misses projects whose UI and WinRT code are in separate files and cannot observe private repositories.
- All figures are snapshots and cannot be converted directly into market share.
Primary sources
- pywinrt repository
- pywinrt changelog
- pywinrt runtime API
- pywinrt WinUI 3 documentation
- PyPI: winrt-runtime
- PyPI: winsdk
- PyPI: winrt
- pepy.tech: winrt-runtime
- pepy.tech: winui3-Microsoft.UI.Xaml
- Qt for Python: QtAsyncio
- qasync
- wx.App event loop
- Toga Windows backend
- pywebview architecture
- Microsoft COM apartment documentation