Metadata-Version: 2.5
Name: refast
Version: 0.12.1
Summary: Python + React UI framework for building reactive web applications
Author-email: Najeem Muhammed <najeem@gmail.com>
License-Expression: MIT
Classifier: Development Status :: 3 - Alpha
Classifier: Framework :: FastAPI
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Python: >=3.11
Requires-Dist: fastapi>=0.104.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: python-multipart>=0.0.6
Requires-Dist: uvicorn>=0.24.0
Requires-Dist: websockets>=12.0
Description-Content-Type: text/markdown

# Refast

**Python + React UI Framework for Building Reactive Web Applications**

[![PyPI Version](https://img.shields.io/pypi/v/refast.svg)](https://pypi.org/project/refast/)
[![Supported Python Versions](https://img.shields.io/pypi/pyversions/refast.svg)](https://pypi.org/project/refast/)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/idling-mind/refast/blob/main/LICENSE)

Refast is a modern, high-performance web framework that enables building reactive single-page applications (SPAs) entirely in **Python**. It uses **FastAPI** for the backend server and compiles a high-fidelity **React** frontend powered by **shadcn/ui** and **Tailwind CSS**. Communication between Python and React happens seamlessly in real-time over a persistent WebSocket connection.

📖 **Documentation**: For full component guides and API references, visit [refast.fastapicloud.com](https://refast.fastapicloud.com).

---

## Quick Start

Get up and running with a simple reactive application in a few minutes.

### 1. Installation

Install Refast and its production dependencies using `pip` or `uv`:

```bash
pip install refast
```

### 2. Code Example

Create a file named `app.py` and add the following code:

```python
import uvicorn
from fastapi import FastAPI
from refast import RefastApp, Context
from refast import components as rc

# Initialize the Refast application
ui = RefastApp(title="Refast Quick Start")

# Define an asynchronous callback for interactivity
async def handle_click(ctx: Context):
    # Targeted text update using the component's ID (highly efficient!)
    await ctx.update_text("status-text", "Refast is reactive! 🚀")
    
    # Trigger a beautiful toast notification
    await ctx.show_toast("Message updated!", variant="success")

# Define a synchronous page layout handler
@ui.page("/")
def home(ctx: Context):
    return rc.Container(
        children=[
            rc.Column(
                children=[
                    rc.Heading("Hello, Refast!", level=1),
                    rc.Text(
                        "Click the button below to trigger a reactive update.",
                        id="status-text",
                        class_name="text-muted-foreground text-center"
                    ),
                    rc.Button(
                        "Click Me",
                        on_click=ctx.callback(handle_click)
                    ),
                ],
                gap=4,
                align="center",
            )
        ],
        class_name="p-8 max-w-md mx-auto mt-20 border rounded-lg shadow-sm bg-card"
    )

# Mount the Refast router to a FastAPI app
app = FastAPI()
app.include_router(ui.router)

if __name__ == "__main__":
    # Start the local development server
    uvicorn.run(app, host="127.0.0.1", port=8000)
```

Run the application:

```bash
python app.py
```

Now open [http://127.0.0.1:8000](http://127.0.0.1:8000) in your browser!

---

## Why Refast?

Traditional web development requires managing separate backend APIs and frontend codebases, dealing with state synchronization, and writing JavaScript. Refast removes these friction points:

- **Write Python Only**: Define your user interface, styling, layout, database interactions, and state mutations purely in Python.
- **Instant React Reactivity**: Components react instantly to server-side state updates over WebSockets without full-page reloads.
- **Beautiful Out-of-the-Box Components**: Native integration with pre-styled, accessible `shadcn/ui` components (Buttons, Inputs, DataTables, Dialogs, Tabs, Calendars, Tooltips, etc.).
- **Fine-Grained DOM Control**: Low-latency Context API updates (e.g., append list items, change element classes, swap subtrees, or update text fields directly) to keep interfaces fast and snappy.
- **Easy Styling**: Apply styling using Tailwind utility classes (`class_name="..."`) or inline styles (`style={...}`) directly on components.
- **Extensible**: Highly extensible. Easily build and register custom components or write extensions to integrate with third-party React/JavaScript libraries.
- **FastAPI Native**: Refast is packaged as a FastAPI router, meaning you can easily mount it into any new or existing FastAPI application.

---

## Architecture & Core Mental Model

Refast divides application code into two distinct types of functions:

1. **Page Handlers (Sync `def`)**: Run on initial page load or when a section requires a fresh layout. They build and return a component tree.
2. **Callback Handlers (Async `async def`)**: Run when a user interacts with the UI (e.g., clicking a button, typing in a field, selecting options). Callbacks mutate state, trigger backend business logic, and send back targeted updates to the browser.

### Minimizing Latency with Targeted DOM Updates

While you can refresh an entire page via `await ctx.refresh()`, Refast encourages high-performance targeted updates to keep latency low. The `Context` object (`ctx`) provides several methods for this:

| Method | Scope / Cost | Recommended Use Case |
| :--- | :--- | :--- |
| `await ctx.update_text(id, text)` | Single string update | Modifying status labels, headers, or counter values. |
| `await ctx.update_props(id, props)` | Prop updates only | Enabling/disabling inputs, changing colors, or toggling state. |
| `await ctx.replace(id, component)` | Subtree replacement | Swapping cards, forms, or content sections. |
| `await ctx.append(id, component)` | Add child element | Adding a new chat message, a log entry, or a list item. |
| `await ctx.prepend(id, component)` | Prepend child element | Adding a message or item at the top of a container. |
| `await ctx.remove(id)` | Delete element | Removing specific list items or alerts from the screen. |
| `await ctx.show_toast(msg)` | Toast notification | Alerting users about action outcomes (success, error). |
| `await ctx.refresh(target_id=...)` | Target subtree re-render | Re-running page logic for a specific container. |

---

## Callbacks & Interactions

Refast supports several types of callbacks to handle frontend events and bridge the gap between Python and JavaScript:

### 1. Callback Reference Builders (Used in layouts)
These are used to bind event handlers (like `on_click`, `on_change`) to components in your page layouts:

* **Python Callbacks (`ctx.callback`)**: Invokes a Python function on the server via WebSocket.
  ```python
  rc.Button("Save", on_click=ctx.callback(handle_save))
  ```
* **Client-Side JS Callbacks (`ctx.js`)**: Executes inline JavaScript code directly on the client side without a server roundtrip.
  ```python
  rc.Button("Alert", on_click=ctx.js("alert('Hello!')"))
  ```
* **Bound Component Method Callbacks (`ctx.bound_js`)**: Calls a specific method on a React component on the frontend.
  ```python
  rc.Button("Clear Canvas", on_click=ctx.bound_js("canvas-id", "clearCanvas"))
  ```

### 2. Imperative Calls from Python Callbacks
You can execute JavaScript or trigger component methods dynamically from within other Python callbacks using the following async `Context` methods:

* **Execute JavaScript (`ctx.call_js`)**: Triggers immediate client-side JS execution from within a Python callback.
  ```python
  async def handle_save(ctx: Context):
      # ... perform server-side database save ...
      await ctx.call_js("confetti({ particleCount: 100 })")
  ```
* **Call Bound Component Methods (`ctx.call_bound_js`)**: Commands a component to perform a built-in method from within a Python callback.
  ```python
  async def reset_board(ctx: Context):
      # ... reset server-side board state ...
      await ctx.call_bound_js("game-board", "resetState")
  ```

---

## State Management

Refast provides multiple ways to manage application state:

### Per-Connection State (`ctx.state`)
Lives for the duration of the WebSocket connection. If the user refreshes the browser page, it resets.
```python
# Set value
ctx.state["count"] = ctx.state.get("count", 0) + 1

# Get value
count = ctx.state["count"]
```

### Browser Storage (`ctx.store`)
Persists data on the client side using browser storage.
```python
# Persistent localStorage (survives browser restarts)
ctx.store.local.set("user_theme", "dark")

# Session storage (survives tab lifetime)
ctx.store.session.set("wizard_step", 2)
```

---

## Development

To set up a local development environment for Refast:

```bash
# Clone the repository
git clone https://github.com/idling-mind/refast.git
cd refast

# Install in editable mode with development dependencies
pip install -e ".[dev]"

# Run tests
pytest tests/

# Run linting and code quality checks
ruff check src/
```

## License

Refast is released under the [MIT License](LICENSE).
