Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

ViewForge

ViewForge is a modern Python desktop UI framework that renders HTML and web components inside a pywebview window.

It supports component-based rendering, declarative event registration, reactive state with signals, and flexible routing — all in Python.


✨ Features

  • ✅ Component-based architecture (Text, Button, Stack, etc.)
  • 🔗 Declarative event binding via @handler()
  • 🧠 Central Python event router for dynamic dispatch
  • 🧩 Flexible styling via CSS-style dicts
  • 🌐 Built-in router with support for path params and query strings
  • ⚡ Hot reload with Ctrl+R
  • 🔁 Signals for reactive state
  • 📦 Modular, extensible, no build step required

📁 Project Structure

viewforge/
├── core/             # App, Component, Registry
├── ui/               # elements/, layout/, links/
├── routing/          # route decorators, RouterView
├── state/            # Signal, Store
├── rendering/        # DOM and HTML rendering logic
├── utils/            # CSS, JS utilities, case handling
├── adapters/         # Optional UI system adapters (Shoelace, BeerCSS)
├── plugins/          # Debug tools, hot reload
└── main.py           # App entry point

🚀 Getting Started

1. Define a handler

from viewforge.core.registry import handler

@handler()
def handle_click():
    print("Button clicked!")

2. Use the handler in a Button

from viewforge.ui.elements import Button

Button("Click Me", on_click=handle_click)

3. Launch the app

from viewforge.core import App

App().run(lambda: [Button("Hi")])

🧠 How Events Work

  • You define Python handlers with @handler() → they get a unique name like on_handle_click

  • Components like Button render HTML like:

    <sl-button onclick="vf('on_handle_click')">Click</sl-button>
    
  • The global vf(...) JS function relays to Python via pywebview.api.handle_event(...)

  • The Python router calls your function:

    def handle_event(self, name, *args):
        return handler_registry.get()[name](*args)
    

🌐 Routing Example

from viewforge.routing import route

@route("/user/<id>", "User Profile")
def user_profile(params, route):
    return Text(f"Viewing user {params['id']}")

💡 Signals

from viewforge.state import Signal

count = Signal(0)

Button("Increment", on_click=lambda: count.set(count.get() + 1))
Text(lambda: f"Count: {count.get()}")

🔧 Advanced Tips

  • All components support style={} for CSS properties
  • You can nest layout containers like Stack, Box, or build your own
  • Router supports dynamic segments and query strings

📦 Coming Soon

  • ✅ FormGroup with validation
  • 🧭 View decorators for route views
  • 🌈 Light/dark theme switching

🧼 Philosophy

ViewForge is minimal by design — no JavaScript build steps, no virtual DOM diffing — just clean Python and direct HTML rendering.

Build UIs in Python. Render like the web.

Metadata

Release files for viewforge 0.1.0.dev2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for viewforge 0.1.0.dev2
File Size Uploaded
viewforge-0.1.0.dev2.tar.gz 30.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for viewforge 0.1.0.dev2
File Interpreter ABI Platform
viewforge-0.1.0.dev2-py3-none-any.whl Python 3 none any Details

Total release size: 66.6 kB

Release files / viewforge-0.1.0.dev2.tar.gz

Download URL viewforge-0.1.0.dev2.tar.gz
Size 30.0 kB
Tags Source
SHA-256 checksum
How to use checksums
f0aa2078d892ef0cd1f437d34f6b9f1b94b148e09593d0b4d1cfc4389efa6ee0
BLAKE2b-256 checksum
How to use checksums
66af77dccee88228b1ddc9000e074f643c0327bc0582e0ac3363881f32bfbb59
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.3

Release files / viewforge-0.1.0.dev2-py3-none-any.whl

Download URL viewforge-0.1.0.dev2-py3-none-any.whl
Size 36.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
58c385cde19309e67f5440b157f12f498cdc950e3c6dcd1b73ba1d7b14337524
BLAKE2b-256 checksum
How to use checksums
2af03bef4cc11fedf551cad59dc53c6c7350404ad8bd8e985114941f3071d573
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.3
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page