ReactPy v2.0.0 Release Notes

Release Date: 2026-02-07 // 4 months ago
  • 📦 Full rewrite of event-to-object. This package no longer uses a white-list to determine what is serializable.

    📦 Instead, this package now attempts to serialize every event property possible up until the defined max-depth. Properties are ignored if they are a non-serializable type, or they fail all known serialization methods.


Previous changes from v2.0.0.b8

  • 🆕 New changes compared to v2.0.0b7

    • 🛠 Fix scenario where @component decorated functions would fail to render as a child of a Client Side Component (CSR).
    • Fix use_async_effect cleanup functions not executing when dependencies have changed

    Summary

    Welcome to the latest beta release of ReactPy v2 , which brings ReactPy Standalone and ReactPy Middleware!

    Here is a quick demo of the new ReactPy Standalone:

    # FILENAME: example.py# Install dependencies: pip install reactpy[asgi]==2.0.0b8 uvicorn[standard]fromreactpyimportcomponent,htmlfromreactpy.executors.asgiimportReactPy@componentdefExampleComponent():returnhtml.div("Hello World")app=ReactPy(ExampleComponent)# Now you can run `uvicorn example:app --reload` to start ReactPy!
    

    Here is a quick demo of the new ReactPy Middleware (using FastAPI for demonstration purposes):

    # FILENAME: example.py# Install dependencies: pip install reactpy[asgi, jinja]==2.0.0b8 uvicorn[standard] starlettefromfastapiimportFastAPI,Requestfromfastapi.responsesimportHTMLResponsefromfastapi.staticfilesimportStaticFilesfromfastapi.templatingimportJinja2Templatesfromreactpyimportcomponent,htmlfromreactpy.executors.asgiimportReactPyMiddleware# Follow your framework's documentation on installing Jinja extensions. You will need to install# ReactPy's Jinja extension to use ReactPy's `{% component "example.path" %}` template tag.fastapi\_app=FastAPI()fastapi\_app.mount("/static",StaticFiles(directory="static"),name="static")templates=Jinja2Templates(directory="templates",extensions=["reactpy.templatetags.ReactPyJinja"])@fastapi\_app.get("/", response\_class=HTMLResponse)asyncdefhomepage(request:Request):# Note: Use ReactPy's template tag in any Jinja template to render a component.returntemplates.TemplateResponse(request,"index.html")@component # Note: Component is declared in this file to simplify the demo.defHelloWorld():returnhtml.div("Hello, World!")# Register components with ReactPy to allow them to be used in your templatesapp=ReactPyMiddleware(fastapi\_app,root\_components=["example.HelloWorld"])# Now you can run `uvicorn example:app --reload` to start ReactPy!
    
    \<!-- FILENAME: index.html --\><!DOCTYPE html>
    <htmllang="en">
    <head>
        <metacharset="UTF-8">
        <metaname="viewport"content="width=device-width, initial-scale=1.0">
        <title>Example Webpage</title>
    </head>
    <body>
        <h1>Welcome to the Example Webpage</h1>{%component"example.HelloWorld"%}</body>
    </html>
    

    🔄 Changelog

    Added

    • ➕ Added support for Python 3.12, 3.13, and 3.14.
    • ➕ Added type hints to reactpy.html attributes.
    • ➕ Added support for nested components in web modules
    • ➕ Added support for inline JavaScript as event handlers or other attributes that expect a callable via reactpy.types.InlineJavaScript
    • 0️⃣ Event functions can now call event.preventDefault() and event.stopPropagation() methods directly on the event data object, rather than using the @event decorator.
    • 👍 Event data now supports accessing properties via dot notation (ex. event.target.value).
    • ➕ Added reactpy.types.Event to provide type hints for the standard data function argument (for example def on_click(event: Event): ...).
    • ➕ Added asgi and jinja installation extras (for example pip install reactpy[asgi, jinja]).
    • ➕ Added reactpy.executors.asgi.ReactPy that can be used to run ReactPy in standalone mode via ASGI.
    • ➕ Added reactpy.executors.asgi.ReactPyCsr that can be used to run ReactPy in standalone mode via ASGI, but rendered entirely client-sided.
    • ➕ Added reactpy.executors.asgi.ReactPyMiddleware that can be used to utilize ReactPy within any ASGI compatible framework.
    • Added reactpy.templatetags.ReactPyJinja that can be used alongside ReactPyMiddleware to embed several ReactPy components into your existing application. This includes the following template tags: {% component %}, {% pyscript_component %}, and {% pyscript_setup %}.
    • ➕ Added reactpy.pyscript_component that can be used to embed ReactPy components into your existing application.
    • Added reactpy.use_async_effect hook.
    • ➕ Added reactpy.Vdom primitive interface for creating VDOM dictionaries.
    • Added reactpy.reactjs.component_from_file to import ReactJS components from a file.
    • Added reactpy.reactjs.component_from_url to import ReactJS components from a URL.
    • Added reactpy.reactjs.component_from_string to import ReactJS components from a string.
    • Added reactpy.reactjs.component_from_npm to import ReactJS components from NPM.
    • ➕ Added reactpy.h as a shorthand alias for reactpy.html.

    🔄 Changed

    • The key attribute is now stored within attributes in the VDOM spec.
    • Substitute client-side usage of react with preact.
    • 👍 Script elements no longer support behaving like effects. They now strictly behave like plain HTML scripts.
    • The reactpy.html module has been modified to allow for auto-creation of any HTML nodes. For example, you can create a <data-table> element by calling html.data_table().
    • 🔄 Change set_state comparison method to check equality with == more consistently.
    • Add support for rendering @component children within vdom_to_html.
    • Renamed the use_location hook's search attribute to query_string.
    • 📇 Renamed the use_location hook's pathname attribute to path.
    • Renamed reactpy.config.REACTPY_DEBUG_MODE to reactpy.config.REACTPY_DEBUG.
    • ReactPy no longer auto-converts snake_case props to camelCase. It is now the responsibility of the user to ensure that props are in the correct format.
    • 📦 Rewrite the event-to-object package to be more robust at handling properties on events.
    • Custom JS components will now automatically assume you are using ReactJS in the absence of a bind function.
    • 🔨 Refactor layout rendering logic to improve readability and maintainability.
    • @reactpy/client now exports React and ReactDOM.
    • reactpy.html will now automatically flatten lists recursively (ex. reactpy.html(["child1", ["child2"]]))
    • reactpy.utils.reactpy_to_string will now retain the user's original casing for data-* and aria-* attributes.
    • reactpy.utils.string_to_reactpy has been upgraded to handle more complex scenarios without causing ReactJS rendering errors.
    • 🚚 reactpy.core.vdom._CustomVdomDictConstructor has been moved to reactpy.types.CustomVdomConstructor.
    • 🚚 reactpy.core.vdom._EllipsisRepr has been moved to reactpy.types.EllipsisRepr.
    • reactpy.types.VdomDictConstructor has been renamed to reactpy.types.VdomConstructor.
    • REACTPY_ASYNC_RENDERING can now de-duplicate and cascade renders where necessary.
    • REACTPY_ASYNC_RENDERING is now defaulted to True for up to 40x performance improvements in environments with high concurrency.

    🗄 Deprecated

    • reactpy.web.module_from_file is deprecated. Use reactpy.reactjs.component_from_file instead.
    • reactpy.web.module_from_url is deprecated. Use reactpy.reactjs.component_from_url instead.
    • reactpy.web.module_from_string is deprecated. Use reactpy.reactjs.component_from_string instead.
    • reactpy.web.export is deprecated. Use reactpy.reactjs.component_from_* instead.
    • 🗄 reactpy.web.* is deprecated. Use reactpy.reactjs.* instead.

    Removed

    • ✂ Removed support for Python 3.9 and 3.10.
    • Removed the ability to import reactpy.html.* elements directly. You must now call html.* to access the elements.
    • ✂ Removed backend specific installation extras (such as pip install reactpy[starlette]).
    • Removed support for async functions within reactpy.use_effect hook. Use reactpy.use_async_effect instead.
    • Removed deprecated function module_from_template.
    • ✂ Removed deprecated exception type reactpy.core.serve.Stop.
    • ✂ Removed deprecated component reactpy.widgets.hotswap.
    • ✂ Removed reactpy.sample module.
    • Removed reactpy.svg module. Contents previously within reactpy.svg.* can now be accessed via reactpy.html.svg.*.
    • ✂ Removed reactpy.html._ function. Use reactpy.html(...) or reactpy.html.fragment(...) instead.
    • ✂ Removed reactpy.run. See the documentation for the new method to run ReactPy applications.
    • ✂ Removed reactpy.backend.*. See the documentation for the new method to run ReactPy applications.
    • ✂ Removed reactpy.core.types module. Use reactpy.types instead.
    • Removed reactpy.utils.html_to_vdom. Use reactpy.utils.string_to_reactpy instead.
    • Removed reactpy.utils.vdom_to_html. Use reactpy.utils.reactpy_to_string instead.
    • ✂ Removed reactpy.vdom. Use reactpy.Vdom instead.
    • Removed reactpy.core.make_vdom_constructor. Use reactpy.Vdom instead.
    • Removed reactpy.core.custom_vdom_constructor. Use reactpy.Vdom instead.
    • ✂ Removed reactpy.Layout top-level re-export. Use reactpy.core.layout.Layout instead.
    • ✂ Removed reactpy.types.LayoutType. Use reactpy.types.BaseLayout instead.
    • ✂ Removed reactpy.types.ContextProviderType. Use reactpy.types.ContextProvider instead.
    • ✂ Removed reactpy.core.hooks._ContextProvider. Use reactpy.types.ContextProvider instead.
    • ✂ Removed reactpy.web.utils. Use reactpy.reactjs.utils instead.

    🛠 Fixed

    • 🛠 Fixed a bug where script elements would not render to the DOM as plain text.
    • 🛠 Fixed a bug where the key property provided within server-side ReactPy code was failing to propagate to the front-end JavaScript components.
    • 🛠 Fixed a bug where RuntimeError("Hook stack is in an invalid state") errors could be generated when using a webserver that reuses threads.
    • 👍 Allow for ReactPy and ReactJS components to be arbitrarily inserted onto the page with any possible hierarchy.