Reflex 7.11 Cursor/Cline Rules & Best Practices

Note: These rules are based on the latest available Reflex documentation and best practices. For version-specific details, always refer to the official Reflex docs.


Core Structure


State Management

  • Define state classes inheriting from rx.State.
  • All mutable variables must be defined as state vars with type hints.
  • Event handlers must be methods within state classes.
  • Only modify state vars through event handlers.

Example:

class State(rx.State):  
    count: int = 0  # Define vars with type hints  
  
    def increment(self):  
        self.count += 1  # Event handler  

State Management Docs


Component Rules

  • Only use Reflex components for UI building.
  • Use rx.cond and rx.foreach for dynamic UI elements.
  • Components must reference state vars for dynamic content.
  • Bind event triggers (like on_click) to state event handlers.

Frontend Guidelines

  • Keep UI logic in component definitions.
  • Complex logic belongs in the State class (backend).
  • Use layout components like rx.hstack, rx.vstack, etc., for structure.

App Configuration

  • Create app instance with rx.App().
  • Add pages using app.add_page().

Best Practices

  • Use Python type hints for all state vars.
  • Keep event handlers focused and single-purpose.
  • Use proper component composition for complex UIs.
  • Leverage Reflex’s built-in state management.

Reflex Architecture Blog


Essential Reference Example

import reflex as rx  
  
class AppState(rx.State):  
    value: str = ""  
  
    def update(self, new_val: str):  
        self.value = new_val  
  
def index():  
    return rx.hstack(  
        rx.input(  
            value=AppState.value,  
            on_change=AppState.update  
        ),  
        rx.text(AppState.value)  
    )  
  
app = rx.App()  
app.add_page(index)  

Frontend Architecture Rules

Components

  • Components compile to React components under the hood.
  • Use Reflex components like rx.hstack, rx.avatar, and rx.input for UI.
  • Components can have props that affect appearance and functionality.
  • Bind event triggers like on_blur to state event handlers.

How Reflex Works

Layout Components

Common layout components:

  • AspectRatio
  • Box
  • Card
  • Center
  • Container
  • Flex
  • Fragment
  • Grid
  • Inset
  • Section
  • Separator
  • Spacer
  • Stack

Layout Components

Pages

  • Pages must be defined as Python functions.
  • Decorate page functions with @rx.page() to add as routes.
  • Pages can have their own substate defined in the same module.
  • Use templates to maintain consistent layout across pages.

Code Structure


Backend Architecture Rules

State Management

See above; all state is managed via classes inheriting from rx.State.

Database Integration

Reflex integrates with SQLAlchemy:

  • Supports SQLite, Postgres, MySQL.

Python Framework Comparison

FastAPI Backend

Reflex compiles to a FastAPI backend:

  • Runs on port 8000 by default.
  • Connects to frontend via WebSocket.
  • State manager maps client tokens to state.

Event Processing

Events contain:

  • Client token
  • Event handler name
  • Arguments
    Events are queued and processed one at a time; state updates are sent back to frontend.

Project Structure Example

example-app/  
├─ assets/  
├─ example_app/  
│   ├─ components/  
│   │   ├─ __init__.py  
│   │   ├─ auth.py  
│   │   ├─ footer.py  
│   │   ├─ menu.py  
│   │   ├─ navbar.py  
│   ├─ pages/  
│   │   ├─ __init__.py  
│   │   ├─ index.py  
│   ├─ __init__.py  
│   ├─ example_app.py  
│   ├─ models.py  
│   ├─ state.py  
├─ requirements.txt  
├─ rxconfig.py  

Code Structure Docs


Authentication & Security

Reflex supports:

  • Local Auth, Google Auth, Captcha, Magic Link Auth, Clerk Auth.

For RBAC (Role-Based Access Control), implement role checks in your State/event handler logic.

Security Tips:

  • Never store sensitive data in client-accessible state.
  • Use server-side validation for all critical actions.
  • Integrate authentication providers securely.

Database Connections

Reflex uses SQLAlchemy under the hood; you can use standard SQLAlchemy patterns for models and queries.

For external backends (e.g., Supabase), use their Python SDKs within your State/event handler methods.


Testing Best Practices

  1. Write unit tests for all State methods (event handlers).
  2. Test component rendering using Reflex’s test utilities or snapshot testing.
  3. Validate that all routes/pages load without errors.
  4. Mock external dependencies (e.g., database calls) in tests.

Example: Minimal Working App Structure

rxconfig.py

import reflex as rx  
  
config = rx.Config(  
    app_name="example_app",  
    theme=rx.theme(radius="full", accent_color="grass"),  
)  

example_app/example_app.py

import reflex as rx  
from . import state, models  
from .pages import index, login, profile  
  
app = rx.App()  
app.add_page(index)  
app.add_page(login)  
app.add_page(profile)  

example_app/state.py

import reflex as rx  
  
class AuthState(rx.State):  
    """Base state for authentication."""  
    logged_in: bool = False  
    username: str = ""  

example_app/models.py

import reflex as rx  
  
class User(rx.Base):  
    """The user model."""  
    username: str  
    email: str  
    role: str = "user"  

example_app/template.py

from typing import Callable  
import reflex as rx  
from .components.navbar import navbar  
from .components.menu import menu  
  
def template(page: Callable[[], rx.Component]) -> rx.Component:  
    """Base template for all pages."""  
    return rx.vstack(  
        navbar(),  
        rx.hstack(  
            menu(),  
            rx.container(page()),  
        ),  
        width="100%",  
    )  

example_app/components/navbar.py

import reflex as rx  
from ..state import AuthState  
  
class NavbarState(rx.State):  
    show_menu: bool = False  
      
    def toggle_menu(self):  
        self.show_menu = not self.show_menu  
  
def navbar() -> rx.Component:  
    return rx.hstack(  
        rx.heading("Example App"),  
        rx.spacer(),  
        rx.text(AuthState.username),  
        rx.button(  
            "Menu",  
            on_click=NavbarState.toggle_menu,  
        ),  
        width="100%",  
        padding="1em",  
    )  

example_app/components/menu.py

import reflex as rx  
from ..state import AuthState  
  
def menu() -> rx.Component:  
    return rx.box(  
        rx.vstack(  
            rx.link("Home", href="/"),  
            rx.link("Profile", href="/profile"),  
            rx.button(  
                "Logout",  
                on_click=AuthState.logout,  
            ) if AuthState.logged_in else rx.link(  
                "Login",  
                href="/login"  
            ),  
            padding="1em",  
        ),  
        width="200px",  
    )  

example_app/pages/index.py

import reflex as rx  
from ..template import template  
from ..state import AuthState  
  
@rx.page(route="/")  
@template  
def index() -> rx.Component:  
    return rx.vstack(  
        rx.heading("Welcome to Example App"),  
        rx.text(  
            f"Hello {AuthState.username}" if AuthState.logged_in else "Please login"  
        ),  
        width="100%",  
        padding="2em",  
    )  

example_app/pages/login.py

import reflex as rx  
from ..state import AuthState  
from ..template import template  
  
class LoginState(AuthState):  
    """Login page state."""  
  
    def handle_submit(self, form_data: dict):  
        """Handle login form submission."""  
        self.username = form_data["username"]  
        self.logged_in = True  
  
@rx.page(route="/login")  
@template  
def login() -> rx.Component:  
    return rx.vstack(  
        rx.heading("Login"),  
        rx.form(  
            rx.vstack(  
                rx.input(  
                    placeholder="Username",  
                    name="username",  
                ),  
                rx.button("Login", type="submit"),  
                width="100%",  
                spacing="4",  
            ),  
            on_submit=LoginState.handle_submit,  
        ),  
        width="100%",  
        padding="2em",  
    )  

example_app/pages/profile.py

import reflex as rx  
from ..state import AuthState  
from ..template import template  
from ..models import User  
  
class ProfileState(AuthState):  
    """Profile page state."""  
    user: User = User(username="", email="", role="user")  
  
    def update_profile(self, form_data: dict):  
        """Update user profile."""  
        self.user = User(**form_data)  
  
@rx.page(route="/profile")  
@template  
def profile() -> rx.Component:  
    return rx.vstack(  
        rx.heading("Profile"),  
        rx.form(  
            rx.vstack(  
                rx.input(  
                    placeholder="Username",  
                    name="username",  
                    value=ProfileState.user.username,  
                ),  
                rx.input(  
                    placeholder="Email",  
                    name="email",  
                    value=ProfileState.user.email,  
                ),  
                rx.button("Update", type="submit"),  
                width="100%",  
                spacing="4",  
            ),  
            on_submit=ProfileState.update_profile,  
        ),  
        width="100%",  
        padding="2em",  
    )  

References & Further Reading:

  1. Getting Started
  2. Reflex Architecture Blog
  3. How Reflex Works
  4. Layout Components
  5. Code Structure
  6. Tutorial: Data Dashboard
  7. Base Vars

Feel free to build upon this structure and refer back to these rules when generating or reviewing Reflex code!