Build UI for your Bevy app using React. A custom React renderer generates Bevy UI components natively in your Bevy ECS with bidirectional interactivity (e.g. onClick, hover, keyboard events).
- It's just React: Full support for React features including State, Hooks, Context, functional components, etc.
- Built on Bevy UI: Renders directly to
bevy_uicomponents (Node,Text,ImageNode,Button). - Hot Reloading: Supports Vite-based HMR for instant UI updates without recompiling.
Early prototype — don't use this in production yet. Core render/input/examples work (see the demo). Next focus is the typed bridge, host-side interaction styling, and Bevy widgets — not more epic polish on the old foundation. Track progress in docs/PROJECT_PLAN.md.
| Package | Version | Registry |
|---|---|---|
bevy_react (Rust) |
0.1.0 | not published |
bevy-react (npm) |
0.1.0 | not published |
Pinned to Bevy 0.17.3 and React 19. See Bevy version support for the support policy and tracking matrix.
| Demo | Menu | Forms | HUD | Gallery |
|---|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
Component samples |
| Bevy + Vite starter with HMR | Full-screen menu and navigation | TextInput, Checkbox, Slider, Select | ECS stats via ReactBridge |
Storybook-style widget gallery |
See docs/EXAMPLES.md for run instructions.
| Doc | Description |
|---|---|
| Getting Started | Local setup and first UI |
| Style Props | Supported CSS-like style properties |
| Architecture | How the two-runtime bridge works |
| Data Bridge | Push ECS state into React / call Rust from JS |
| Binary Protocol | BRRP batched mutation frames (beside enum RPC) |
| DevTools | Debug WS bridge + node↔Entity inspector |
| Boa Compat | JS APIs that work / are shimmed / missing in Boa |
| Troubleshooting | In-game error overlay, stacks, source maps |
| Examples | Demo, menu, forms, HUD, gallery |
| Demo smoke | Manual checklist + automated smoke script |
| Bevy Version | Support policy + version matrix |
| Project Plan | Bridge-first roadmap |
| Contributing | How to contribute |
| Changelog | Release notes |
Prefer the documented path in Getting Started. Short version:
- Run the Vite UI (
examples/demo/ui) and the Bevy host (examples/demo). - Or path-depend the crate / link the TS package from this repo (packages are not on crates.io/npm yet).
use bevy::prelude::*;
use bevy_react::{ReactBundle, ReactPlugin, ViteDevSource, js_bevy::JsPlugin};
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(JsPlugin)
.add_plugins(ReactPlugin)
.add_systems(Startup, setup)
.run();
}
fn setup(mut commands: Commands) {
commands.spawn(Camera2d);
let js_source = ViteDevSource::default()
.with_entry_point("src/main.tsx")
.into();
commands.spawn(ReactBundle::new(
Node {
width: Val::Percent(50.0),
height: Val::Percent(100.0),
left: Val::Percent(50.0),
position_type: PositionType::Absolute,
..default()
},
js_source,
));
}import { useState } from "react";
import { createBevyApp, Node, Text, Button } from "bevy-react";
function App() {
const [count, setCount] = useState(0);
return (
<Node>
<Text>Count: {count}</Text>
<Button onClick={() => setCount(count + 1)}>Increment</Button>
</Node>
);
}
export default createBevyApp(<App />);bevy-react consists of two parts:
- Host (Rust): A Bevy plugin that embeds the Boa JavaScript engine. It exposes a channel-based protocol for communicating with the UI and JS runtime.
- Client (JS/TS): A custom React Reconciler that translates React Virtual DOM operations into native function calls which are sent back to the Rust host.
See Architecture for details.
MIT — see LICENSE.



