Cross-platform wrapper around native webview components that lets Python applications display HTML content in a native GUI window. Use when building desktop applications with web-based UIs on Windows, macOS, Linux, or Android — including two-way JavaScript↔Python communication, DOM manipulation from Python, built-in HTTP server, window management, and bundler-friendly packaging.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
A direct command skips the review prompt. Inspect the source before running it.
Cross-platform wrapper around native webview components that lets Python applications display HTML content in a native GUI window. Use when building desktop applications with web-based UIs on Windows, macOS, Linux, or Android — including two-way JavaScript↔Python communication, DOM manipulation from Python, built-in HTTP server, window management, and bundler-friendly packaging.
pywebview is a lightweight BSD-licensed cross-platform wrapper around native webview components. It displays HTML content in its own native GUI window, giving you the power of web technologies in a desktop application while hiding the fact that the UI is browser-based.
Key capabilities:
Cross-platform — Windows (WinForms/EdgeChromium/CEF), macOS (Cocoa/WebKit), Linux (GTK or Qt), Android (Kivy)
Two-way JavaScript↔Python communication — call Python from JS and JS from Python without HTTP
Built-in HTTP server — serves local files automatically via Bottle
DOM support in Python — manipulate and traverse DOM nodes without JavaScript
Create windows with webview.create_window() before or during the GUI loop
Start the GUI loop with webview.start() — this blocks until all windows are closed
Backend logic runs in a separate thread via webview.start(func, *args)
import webview
defbackend_logic(window):
"""Runs in a separate thread after the GUI loop starts."""
window.toggle_fullscreen()
window = webview.create_window('My App', html='<h1>Hello</h1>')
webview.start(backend_logic, window)
# Code below runs only after all windows are closed
Content Loading
Three ways to load content into a window:
URL — remote or local path (relative paths auto-start HTTP server)
HTML string — inline HTML content
WSGI app — pass a Flask/FastAPI app object directly
# Remote URL
webview.create_window('Docs', 'https://pywebview.flowrl.com/')
# Inline HTML
webview.create_window('Inline', html='<h1>Hello</h1>')
# Local files (HTTP server starts automatically for relative paths)
webview.create_window('Local', 'src/index.html')
# WSGI appfrom flask import Flask
app = Flask(__name__, static_folder='./assets')
webview.create_window('Flask', app)
Multiple Windows
Create as many windows as needed. All windows are tracked in webview.windows:
import webview
first = webview.create_window('First', 'https://example.com')
second = webview.create_window('Second', 'https://other.com')
# Access the currently focused window
active = webview.active_window()
print(f'Active: {active.title}')
print(f'Total windows: {len(webview.windows)}')
webview.start()
Settings
Global settings override default behavior via webview.settings: