Skip to content

Repository files navigation

Refast

Python + React UI Framework for Building Reactive Web Applications

PyPI Version Supported Python Versions 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.


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:

pip install refast

2. Code Example

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

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:

python app.py

Now open 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.
    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.
    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.
    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.
    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.
    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.

# 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.

# 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:

# 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.

About

Reactive UI framework for python using fastapi and react

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages