Refast
Python + React UI Framework for Building Reactive Web Applications
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/uicomponents (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:
- Page Handlers (Sync
def): Run on initial page load or when a section requires a fresh layout. They build and return a component tree. - 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.
Metadata
Release files for refast 0.12.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| refast-0.12.2.tar.gz | 7.8 MB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| refast-0.12.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 15.4 MB
Release files / refast-0.12.2.tar.gz
| Download URL | refast-0.12.2.tar.gz |
|---|---|
| Size | 7.8 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7f559c05f60f4cbe708b3978b5beb974683cc750241d16a14c82c36ea773ff7c
|
|
BLAKE2b-256 checksum How to use checksums |
90120b1c0ac10257b6bba373280cca6001bd187ff12c98f6e31bbe9fd0e12157
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / refast-0.12.2-py3-none-any.whl
| Download URL | refast-0.12.2-py3-none-any.whl |
|---|---|
| Size | 7.6 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
377cfb3b127a4790da1f35de193be433454fb2bf288e557831874161d3086a47
|
|
BLAKE2b-256 checksum How to use checksums |
97095b83581aa8dc7b07d70b757d36fcec19fd3115c945e0fea31b5012386d5c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for refast 0.12.2
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.