π PyWebView
Good to know
β PyWebView lets you build a desktop GUI using HTML/CSS/JS while keeping Python as the backend. JavaScript can call Python functions (via js_api) and Python can call JS inside the window. Itβs perfect for small tools, dashboards, or lightweight apps without a full web server.
Basic Setup
Creates a window, loads an HTML file, and exposes a Python API class to JavaScript.
import webview
from utils import resource_path
from api import API
if __name__ == "__main__":
# Create an instance of your backend API
py_api = API()
# Path to your HTML frontend (works in dev + PyInstaller)
html_path = resource_path("app/app.html")
# Create the GUI window
my_frontend_window = webview.create_window(
"Generator",
url=html_path,
width=1080,
height=900,
js_api=py_api # attach Python API for JS communication
)
# Called once the GUI window is ready
def on_start():
py_api.window = my_frontend_window
# Start the frontend loop
webview.start(on_start, debug=False)API Class
Your custom backend that exposes Python functions to JavaScript.
class API:
def __init__(self):
self.window = None # gets assigned on startup
def my_function(self, payload_json: str) -> bool:
print("Received from JS:", payload_json)
return True
# Anything defined here can be called from your JS frontend.Calling Python from JavaScript
JS can call your Python API like this:
window.pywebview.api.my_function(JSON.stringify({msg: "Hi"}))
.then(response => console.log(response));JS receives the return value from Python as a Promise.
Calling JavaScript from Python
Python can execute JS inside the WebView window.
self.window.evaluate_js("alert('Hello from Python!')")This makes two-way communication possible.
Useful Tips
Avoid freezing the UI
Long-running tasks should run in threads:
import threading
threading.Thread(target=self.long_task).start()Logging to the JS console
self.window.evaluate_js("console.log('Python says hi')")