| name | pywebview-6-2-1 |
| description | 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 6.2.1
Changelog (6.2.1)
- Bug fix —
Winforms: Fix screen scale reporting in Screen object.
Overview
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
- Window management — size, position, fullscreen, frameless, multi-window
- Native components — menus, file dialogs, confirmation dialogs
- Bundler-friendly — works with PyInstaller, Nuitka, py2app
- Shared state (new in 6.0) — reactive state object synced between Python and JavaScript
pywebview does not bundle a heavy GUI toolkit or web renderer, keeping frozen executables small.
Requires Python 3.8+.
When to Use
- Building desktop applications with HTML/CSS/JavaScript UIs
- Wrapping existing web applications in a native window
- Creating tools that need two-way communication between Python backend and JavaScript frontend
- Prototyping GUIs quickly with web technologies
- Building cross-platform desktop apps without learning platform-specific GUI frameworks
- Distributing Python apps with embedded web content via PyInstaller, Nuitka, or py2app
Installation
pip install pywebview
On Linux, choose a backend explicitly:
pip install pywebview[gtk]
pip install pywebview[qt]
pip install pywebview[qt5]
pip install pywebview[pyside6]
Optional extras:
pywebview[cef] — CEF renderer (Windows only)
pywebview[ssl] — SSL support for local HTTP server
pywebview[android] — Android support
Hello World
import webview
webview.create_window('Hello world', 'https://pywebview.flowrl.com/')
webview.start()
Core Concepts
Application Lifecycle
- 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
def backend_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)
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
webview.create_window('Docs', 'https://pywebview.flowrl.com/')
webview.create_window('Inline', html='<h1>Hello</h1>')
webview.create_window('Local', 'src/index.html')
from 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')
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:
import webview
webview.settings['ALLOW_DOWNLOADS'] = True
webview.settings['OPEN_EXTERNAL_LINKS_IN_BROWSER'] = False
webview.settings['IGNORE_SSL_ERRORS'] = True
Available settings:
ALLOW_DOWNLOADS — allow file downloads (default: False)
ALLOW_FILE_URLS — enable file:// URLs (default: False)
DRAG_REGION_SELECTOR — CSS selector for drag region in frameless windows
DRAG_REGION_DIRECT_TARGET_ONLY — only direct matches are draggable
OPEN_EXTERNAL_LINKS_IN_BROWSER — open target=_blank links externally (default: True)
OPEN_DEVTOOLS_IN_DEBUG — auto-open DevTools in debug mode (default: True)
IGNORE_SSL_ERRORS — ignore SSL certificate errors (default: False)
REMOTE_DEBUGGING_PORT — port for remote debugging (edgechromium/qt)
SHOW_DEFAULT_MENUS — show default menus on macOS (default: True)
WEBVIEW2_RUNTIME_PATH — path to bundled WebView2 runtime
Usage Examples
Basic Window with Events
import webview
def on_closing():
print('Window is about to close')
def on_loaded(window):
print(f'Page loaded: {window.get_current_url()}')
window = webview.create_window('My App', 'https://example.com')
window.events.closing += on_closing
window.events.loaded += lambda: on_loaded(window)
webview.start()
JavaScript to Python Communication
import webview
class Api:
def greet(self, name):
return f'Hello, {name}!'
def add(self, a, b):
return a + b
html = '''
<button onclick="callPython()">Call Python</button>
<script>
window.addEventListener('pywebviewready', () => {
pywebview.api.greet('World').then(result => alert(result));
});
</script>
'''
webview.create_window('JS API', html=html, js_api=Api())
webview.start()
Shared State (6.0+)
import webview
html = '''
<button onclick="pywebview.state.counter++">Increment</button>
<span id="counter"></span>
<script>
window.addEventListener('pywebviewready', () => {
pywebview.state.addEventListener('change', e => {
document.getElementById('counter').innerText = pywebview.state.counter;
});
});
</script>
'''
def on_change(event_type, key, value):
print(f'{event_type}: {key} = {value}')
window = webview.create_window('State', html=html)
window.state.counter = 0
window.state += on_change
webview.start()
Window with SSL and Custom User Agent
import webview
webview.create_window('Secure', 'src/index.html')
webview.start(ssl=True, user_agent='MyApp/1.0')
Advanced Topics
Full API Reference: create_window, start, Window methods, events → API Reference
JavaScript↔Python Bridge: JS API, expose, shared state, evaluate_js, run_js → JavaScript-Python Bridge
DOM Support: Element manipulation, traversal, events from Python → DOM Support
Platforms and Renderers: Web engines per platform, installation, dependencies → Platforms and Renderers
Advanced Topics: Freezing/bundling, security, debugging, HTTP server, menus, file dialogs → Advanced Topics