Metadata-Version: 2.4
Name: echoui
Version: 0.9.3
Summary: Universal Python-first UI framework — one Screen-Stage-Sprite paradigm compiles to Web, desktop, mobile, TUI, and GUI, with a universal escape layer guaranteeing capability parity with any framework.
Project-URL: Homepage, https://github.com/nichengfuben/echoui
Project-URL: Documentation, https://echoui.dev
Author-email: nichengfuben <nichengfuben@outlook.com>
License: MIT
License-File: LICENSE
Keywords: compiler,desktop,framework,fullstack,gui,mobile,tui,ui,web
Requires-Python: >=3.11
Requires-Dist: csscompressor>=0.9.5
Requires-Dist: rjsmin>=1.2.2
Requires-Dist: watchfiles>=0.21.0
Provides-Extra: all
Requires-Dist: aiohttp>=3.9.5; extra == 'all'
Requires-Dist: box2d-py>=2.3.10; extra == 'all'
Requires-Dist: build>=1.2.1; extra == 'all'
Requires-Dist: fastapi>=0.110.0; extra == 'all'
Requires-Dist: hatchling; extra == 'all'
Requires-Dist: msgpack>=1.0.8; extra == 'all'
Requires-Dist: mypy>=1.9.0; extra == 'all'
Requires-Dist: playwright>=1.43.0; extra == 'all'
Requires-Dist: pyarrow>=15.0.2; extra == 'all'
Requires-Dist: pyinstaller>=6.6.0; extra == 'all'
Requires-Dist: pyside6>=6.7.0; extra == 'all'
Requires-Dist: pytest-asyncio>=0.23.6; extra == 'all'
Requires-Dist: pytest-qt>=4.4.0; extra == 'all'
Requires-Dist: pytest>=8.1.1; extra == 'all'
Requires-Dist: rich>=13.7.1; extra == 'all'
Requires-Dist: ruff>=0.4.1; extra == 'all'
Requires-Dist: textual>=0.58.0; extra == 'all'
Requires-Dist: twine>=5.1.1; extra == 'all'
Requires-Dist: uvicorn[standard]>=0.29.0; extra == 'all'
Provides-Extra: data
Requires-Dist: pyarrow>=15.0.2; extra == 'data'
Provides-Extra: desktop
Requires-Dist: pyinstaller>=6.6.0; extra == 'desktop'
Requires-Dist: pyside6>=6.7.0; extra == 'desktop'
Provides-Extra: dev
Requires-Dist: build>=1.2.1; extra == 'dev'
Requires-Dist: hatchling; extra == 'dev'
Requires-Dist: mypy>=1.9.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23.6; extra == 'dev'
Requires-Dist: pytest>=8.1.1; extra == 'dev'
Requires-Dist: ruff>=0.4.1; extra == 'dev'
Requires-Dist: twine>=5.1.1; extra == 'dev'
Provides-Extra: dev-extended
Requires-Dist: playwright>=1.43.0; extra == 'dev-extended'
Requires-Dist: pytest-qt>=4.4.0; extra == 'dev-extended'
Provides-Extra: fastapi
Requires-Dist: fastapi>=0.110.0; extra == 'fastapi'
Requires-Dist: uvicorn[standard]>=0.29.0; extra == 'fastapi'
Provides-Extra: gui
Requires-Dist: pyside6>=6.7.0; extra == 'gui'
Provides-Extra: mobile
Provides-Extra: physics
Requires-Dist: box2d-py>=2.3.10; extra == 'physics'
Provides-Extra: tui
Requires-Dist: rich>=13.7.1; extra == 'tui'
Requires-Dist: textual>=0.58.0; extra == 'tui'
Provides-Extra: web
Requires-Dist: aiohttp>=3.9.5; extra == 'web'
Requires-Dist: msgpack>=1.0.8; extra == 'web'
Description-Content-Type: text/markdown

# EchoUI — Universal Python-first UI framework

One **Screen–Stage–Sprite** paradigm compiles to Web, desktop, mobile, TUI, and GUI.

**Version:** 0.9.0 · **License:** MIT · **Docs:** [docs/api/INDEX.md](docs/api/INDEX.md)

## Quick Start

```bash
pip install -e ".[web,dev]"
```

Create `main.py`:

```python
from echoui import App, Screen, Store, col, text, button

class CounterStore(Store):
    count: int = 0

store = CounterStore()

class Counter(Screen):
    def build(self):
        return col(
            text(lambda: f"Count: {store.count}"),
            button("+1", on_click=lambda: setattr(store, "count", store.count + 1)),
        )

app = App(screens=[Counter], initial="Counter")
```

Build and run:

```bash
echoui build --target web
echoui dev --target web --port 7999
```

Open http://127.0.0.1:7999 — click **+1** and the count increments.

## CLI

| Command | Description |
|---------|-------------|
| `echoui new [name]` | Scaffold a counter project |
| `echoui dev --target web` | Dev server with hot reload |
| `echoui build --target web\|static\|tui\|desktop\|gui` | Compile for target |
| `echoui check` | Validate project |
| `echoui version` | Print version |

## Quality Gate

```bash
ruff check .
mypy echoui
pytest -q
python achecker.py
python -m build
twine check dist/*
```

## Testing

```bash
pytest -q
```

## License

MIT — see [LICENSE](LICENSE).
