Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Dry

Dry is a Python library that opens one native window rendering a web frontend, plus a Bridge between that frontend and Python. It is written in Rust on top of Wry, ships as a compiled extension module, and depends on nothing but the Python standard library.

from dry import Webview

wv = Webview(
    app_id='com.example.hello',
    title='Hello',
    html='<h1>Hello from Dry</h1>',
)
wv.run()

wv.run() opens the window and does not come back. Closing the window exits the process, so nothing written after it runs.

What is in scope

Anything a frontend legitimately needs from its host window: the window itself, its titlebar and edges, what it renders, and a channel to Python. General application concerns — filesystem access, databases, HTTP clients — are not. Those are Python’s, and the developer wires them through the Bridge.

The shape of the library

There is one public object, the Webview, and one channel, the Bridge. The Bridge carries exactly two message shapes, and both travel in both directions:

Frontend to PythonPython to frontend
Call — returns a valuewindow.dry.api.name(...)deliberately absent; use wv.eval_js
Event — returns nothingwindow.dry.emit(name, value)wv.emit(name, value)

The missing quadrant is a decision, not an omission: a Python-side await on the frontend never resolves if the page navigates or hangs. When the answer matters, have the frontend Call Python.

Where to go next

The vocabulary used throughout this site — Webview, Bridge, Call, Event, Api, Portal, Content, Root, Drag region, Resize edge, Bridge contract, Close hook, App id — is defined in CONTEXT.md and used with exactly those meanings.