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!