🐍 PyReact — Declarative Web Framework for Python
PyReact is a React-inspired declarative web framework built natively for Python. It provides reactive user interfaces, components, hooks, efficient rendering, server-side rendering, and a project CLI.
Installation
pip install pyreact-framework
Install the current GitHub version:
pip install git+https://github.com/wanbnn/pyreact.git
Set up a local development checkout:
git clone https://github.com/wanbnn/pyreact.git
cd pyreact
pip install -e ".[dev]"
Quick start
Create and run a project:
pyreact create my-app
cd my-app
pyreact dev
A functional counter:
from pyreact import h, render, use_state
def Counter(props):
count, set_count = use_state(0)
return h(
"div",
{"className": "counter"},
h("h1", None, f"Count: {count}"),
h("button", {"onClick": lambda: set_count(count + 1)}, "+"),
h("button", {"onClick": lambda: set_count(count - 1)}, "-"),
)
root = document.getElementById("root")
render(h(Counter, None), root)
Components
Functional components are plain Python callables:
def Button(props):
return h(
"button",
{"className": "btn", "onClick": props.get("onClick")},
props.get("children"),
)
Class components extend Component:
from pyreact import Component, h
class Counter(Component):
def __init__(self, props):
super().__init__(props)
self.state = {"count": 0}
def render(self):
return h(
"button",
{"onClick": lambda: self.set_state({"count": self.state["count"] + 1})},
f"Count: {self.state['count']}",
)
Hooks
from pyreact import h, use_effect, use_ref, use_state
def MyComponent(props):
count, set_count = use_state(0)
use_effect(lambda: print(f"Count: {count}"), [count])
input_ref = use_ref(None)
return h("div", None, f"Count: {count}")
Main API
h(type, props, *children)creates a virtual element (VNode).render(element, container)renders an element into a DOM container.create_root(container)creates a modern rendering root.render_to_string(element)renders hydratable server-side markup.render_to_static_markup(element)renders static HTML.
See the complete API reference.
CLI
pyreact create <name>
pyreact dev [--port PORT] [--no-open]
pyreact generate component <name>
pyreact generate hook <name>
pyreact build
Testing
# Complete test suite
python -m pytest -q
# End-to-end tests
python -m pytest tests/e2e -q
# Coverage
python -m pytest --cov=pyreact --cov-report=term-missing
See the execution and testing guide.
Project layout
pyreact/
├── pyreact/ # Framework source
│ ├── cli/ # Command-line interface
│ ├── core/ # Components, hooks, and VNodes
│ ├── dom/ # DOM operations
│ ├── server/ # Server-side rendering
│ └── utils/ # Utilities
├── tests/ # Unit and end-to-end tests
├── examples/ # Usage examples
├── boilerplate/ # Complete generated application
├── docs/ # Sphinx and Markdown documentation
├── pyproject.toml
└── LICENSE
Development
python -m venv .venv
# Linux/macOS: source .venv/bin/activate
# Windows: .venv\Scripts\activate
python -m pip install -e ".[dev,e2e]"
python -m playwright install chromium
python -m pytest -q
python -m build
Publishing
Every push to master runs tests, builds distributions, and publishes to PyPI
through GitHub Actions. Authentication uses PyPI Trusted Publishing (OIDC), so
the repository does not store a permanent upload token. See the
automatic publishing guide.
Contributing
Contributions are welcome:
- Fork the repository.
- Create a focused branch.
- Include tests with your change.
- Run the complete test suite.
- Open a pull request explaining the problem and solution.
Documentation
The complete English documentation is published at https://pyreact-framework.readthedocs.io/.
License
PyReact is licensed under the MIT License. See LICENSE.
Metadata
Release files for pyreact-framework 1.0.5.post3028994678301
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pyreact_framework-1.0.5.post3028994678301.tar.gz | 61.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pyreact_framework-1.0.5.post3028994678301-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 128.2 kB
Release files / pyreact_framework-1.0.5.post3028994678301.tar.gz
| Download URL | pyreact_framework-1.0.5.post3028994678301.tar.gz |
|---|---|
| Size | 61.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e1bf4b6b124a4b8bbda4fbe46413d003402fd21969fff6cc86798fd4f255c672
|
|
BLAKE2b-256 checksum How to use checksums |
ef46efd1622aea3d0c8568eccc8dedf3c5b9ecd449904552db452de006d78d89
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 27, 2026.
Transparency logRelease files / pyreact_framework-1.0.5.post3028994678301-py3-none-any.whl
| Download URL | pyreact_framework-1.0.5.post3028994678301-py3-none-any.whl |
|---|---|
| Size | 66.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
166e3baa4419745b33173020bb0ab2c41d44b740d604c96832144ef069007441
|
|
BLAKE2b-256 checksum How to use checksums |
43edc35111a7f4f2144e2481be22258721ddb0ddaf456c7baa12b18a0e5c7d36
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 27, 2026.
Transparency log