Concepts

Architecture

Wry Py wraps Rust libraries via PyO3:

  • Wry - Cross-platform webview

  • Tao - Window and event handling

Elements are serialized to HTML/CSS and rendered in the native webview.

Builders and Elements

ElementBuilder is mutable and supports method chaining. Call .build() to get an immutable Element.

# ElementBuilder
builder = div().size_full().bg("#fff")

# Element
element = builder.build()

Use .child_builder() to add children without manually calling .build():

div().child_builder(text("Hello"))  # calls .build() internally

Element Types

  • div() - Container

  • text(content) - Text display

  • button(label) - Button with click handler

  • input() - Text input with input handler

  • image(src) - Image

  • checkbox(label) - Checkbox with optional label

  • radio(label) - Radio button with optional label

  • select() - Dropdown select

Styling States

Elements support hover and focus styles:

button("Submit")
.bg("#fafafa")
.hover_bg("#d4d4d4")
.transition_all(0.2)

input()
.border(1, "#404040")
.focus_border_color("#a3a3a3")

Available transitions:

  • transition_all(seconds) - all properties

  • transition_colors(seconds) - background, text, border colors

  • transition_transform(seconds) - scale, etc.

Event Handling

Click:

def on_click():
    print("clicked")

button("Click").on_click(on_click)

Input:

def on_input(value: str):
    print(value)

input().on_input(on_input)

Mouse events:

div()
.on_mouse_enter(on_enter)
.on_mouse_leave(on_leave)

Callbacks run synchronously in the event loop.

Updating UI

Rebuild and call set_root():

def render():
    root = div().child_builder(text(f"Value: {state}")).build()
    window.set_root(root)

DOM Patching

Elements are patched in place rather than replaced. This preserves CSS transition state so animations work smoothly across re-renders.

Add transitions to see smooth updates:

text(f"Count: {count}")
.text_color(get_color())
.transition_colors(0.3)

The Event Loop

window.run() blocks until the window closes. Use window.close() to exit programmatically.

def quit():
    window.close()

button("Quit").on_click(quit)

Platform Backends

  • Windows - WebView2 (Edge)

  • macOS - WebKit (Safari)

  • Linux - WebKitGTK (requires GTK libraries)