mirror of
https://github.com/remorses/gpuix.git
synced 2026-10-28 18:59:22 +08:00
5.3 KiB
5.3 KiB
GPUIX
React bindings for GPUI - Zed's GPU-accelerated UI framework.
Architecture
GPUIX bridges React to GPUI using a description-based renderer that matches GPUI's immediate-mode architecture:
┌─────────────────────────────────────────────────────────┐
│ React (JavaScript) │
│ │
│ function App() { │
│ const [count, setCount] = useState(0) │
│ return ( │
│ <div style={{ display: 'flex', gap: 8 }}> │
│ <text>Count: {count}</text> │
│ <div onClick={() => setCount(c => c + 1)}> │
│ Click me │
│ </div> │
│ </div> │
│ ) │
│ } │
└─────────────────────────────────────────────────────────┘
↓ JSON element tree
┌─────────────────────────────────────────────────────────┐
│ Rust (napi-rs) │
│ │
│ // Rebuild GPUI elements from description each frame │
│ fn build_element(desc: &ElementDesc) -> AnyElement │
└─────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ GPUI │
│ │
│ GPU-accelerated rendering via Metal/Vulkan │
└─────────────────────────────────────────────────────────┘
Why This Works
GPUI is an immediate-mode UI framework - it rebuilds the entire element tree every frame. This actually aligns perfectly with React's declarative model:
- React reconciler builds a virtual element tree
- Tree is serialized to JSON and sent to Rust via napi-rs
- Rust rebuilds GPUI elements from the description
- GPUI renders to GPU
Packages
@gpuix/native- Rust/napi-rs bindings to GPUI@gpuix/react- React reconciler and components
Building
Prerequisites
- Rust toolchain
- Node.js 18+
- Xcode with Metal Toolchain (macOS)
# Install Metal Toolchain if needed
xcodebuild -downloadComponent MetalToolchain
# Install dependencies
bun install
# Build native package
cd packages/native
bun run build
# Build React package
cd ../react
bun run build
# Run example (use tmux for long-running sessions)
cd ../../examples
npx tsx counter.tsx
Usage
import { createRoot, flushSync, GpuixRenderer } from '@gpuix/react'
// Create the native renderer
const renderer = new GpuixRenderer((event) => {
// Handle events from GPUI
console.log('Event:', event)
})
// Create React root
const root = createRoot(renderer)
// Render your app
flushSync(() => {
root.render(<App />)
})
// Start the GPUI event loop
renderer.run()
Supported Elements
| Element | Description |
|---|---|
div |
Container with flexbox layout |
text |
Text content |
img |
Images |
svg |
Vector graphics |
canvas |
Custom drawing |
Supported Events
onClick,onMouseDown,onMouseUponMouseEnter,onMouseLeave,onMouseMoveonKeyDown,onKeyUponFocus,onBluronScroll
Supported Styles
Tailwind-like styling via the style prop:
<div style={{
display: 'flex',
flexDirection: 'column',
gap: 8,
padding: 16,
backgroundColor: '#3b82f6',
borderRadius: 8,
}}>
<text style={{ color: '#ffffff', fontSize: 18 }}>
Hello GPUI!
</text>
</div>
Status
⚠️ Work in Progress
- React reconciler (based on opentui)
- Element tree serialization
- napi-rs bindings structure
- Style mapping (CSS → GPUI)
- Event callback system
- GPUI element building (build_element, apply_styles)
- Event wiring (click, mouseDown, mouseUp, mouseMove)
- Standalone build - Pinned GPUI and macOS deps for compatibility
- Focus management
- Keyboard events
- Text input
Current Blocker
None currently. If native builds regress, check the GPUI pin and macOS core-text/core-graphics versions in packages/native/Cargo.toml.
Documentation
See AGENTS.md for detailed architecture, communication flow, and contributing guide.
License
Apache-2.0