Python state, React UI.
RemoteState is a Python-first framework for building stateful React frontends. Python owns the state and behavior, while React owns the presentation. Use it when you want a single source of truth in Python and a typed TypeScript bridge in the browser.
It fits especially well for:
- notebook apps where Python drives the workflow
- frontend addons or plugins that need an optional Python backend
- teams that want one runtime for state, actions, queries, and progress updates
If you want a pure client-side React state library with no Python backend, RemoteState is probably not the right fit.
- Python-owned
Storestate with path-based reads and writes @actionand@querymethods for mutating and read-only calls- WebSocket synchronization between Python and React
- typed TypeScript client, provider, and hooks
- task and progress updates from long-running work
- notebook and browser serving from the Python runtime
- optional local fallback clients for addon-style apps
- Python is the source of truth for business state and behavior
- TypeScript/React renders the UI and calls into Python when needed
- the WebSocket bridge carries reads, writes, queries, actions, and task updates
import remotestate as rs
class Counter(rs.Service):
def __init__(self) -> None:
super().__init__(rs.Store({"count": 0}))
@rs.action
async def increment(self) -> None:
self.store.set("count", self.store.get("count") + 1)
service = Counter()
rs.serve(service, ui_dist="ui/dist")import {
RemoteStateProvider,
useRemoteState,
useRemoteStateClient,
} from "remotestate";
type CounterService = {
increment(): Promise<void>;
};
function Counter() {
const client = useRemoteStateClient<CounterService>();
const [count, setCount] = useRemoteState<number>("count", 0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => void setCount((n) => (n ?? 0) + 1)}>
Local +1
</button>
<button onClick={() => void client.action("increment")}>
Backend +1
</button>
</div>
);
}
export default function App() {
return (
<RemoteStateProvider url="ws://localhost:9753/ws">
<Counter />
</RemoteStateProvider>
);
}MIT © @forman