| Crates.io | deckyfx-dioxus-react-integration |
| lib.rs | deckyfx-dioxus-react-integration |
| version | 0.1.0 |
| created_at | 2025-11-03 01:33:01.463913+00 |
| updated_at | 2025-11-03 01:33:01.463913+00 |
| description | Serve React apps with Dioxus runtime and IPC bridge |
| homepage | |
| repository | https://github.com/deckyfx/LearningDioxus |
| max_upload_size | |
| id | 1913770 |
| size | 149,772 |
Serve React applications within the Dioxus runtime, combining the best of both worlds: native Dioxus capabilities with React's ecosystem.
[dependencies]
dioxus = "0.7.0-rc.1"
dioxus-ipc-bridge = "0.1"
dioxus-react-integration = "0.1"
# Optional: Enable asset registry
# dioxus-react-integration = { version = "0.1", features = ["asset-registry"] }
# Create React app with Vite
npm create vite@latest my-react-app -- --template react-ts
cd my-react-app
# Copy TypeScript definitions
cp path/to/types.ts src/
# Build for production
npm run build
use dioxus::prelude::*;
use dioxus_react_integration::prelude::*;
// Define React bundle as asset
const REACT_BUNDLE: Asset = asset!("/assets/react/bundle.js");
fn main() {
dioxus::launch(App);
}
#[component]
fn App() -> Element {
// Set up IPC bridge
let router = use_signal(|| {
IpcRouter::builder()
.route("GET", "/hello/:name", Box::new(HelloHandler))
.build()
});
// Initialize bridge
use_effect(move || {
let bridge = IpcBridge::builder().build();
bridge.initialize();
// Start IPC listener...
});
rsx! {
ReactContainer {
bundle: REACT_BUNDLE,
mount_id: "react-root".to_string()
}
}
}
// src/App.tsx
import { ipcRequest } from './types';
function App() {
const [greeting, setGreeting] = useState('');
useEffect(() => {
// Call Rust backend
ipcRequest<{ message: string }>('ipc://hello/World')
.then(data => setGreeting(data.message));
}, []);
return <div>{greeting}</div>;
}
For dynamic asset loading:
[dependencies]
dioxus-react-integration = { version = "0.1", features = ["asset-registry"] }
use dioxus_react_integration::prelude::*;
// Register assets
let mut registry = AssetRegistry::new();
registry.register("logo".to_string(), asset!("/assets/logo.png").to_string());
// Access from JavaScript
// window.dioxusBridge.fetch('ipc://assets/logo')
// Advanced setup with custom configuration
#[component]
fn App() -> Element {
rsx! {
// Custom mount point and bundle
ReactContainer {
bundle: asset!("/dist/main.js"),
mount_id: "app-root".to_string()
}
// You can mix Dioxus and React!
div {
class: "dioxus-sidebar",
"This is rendered by Dioxus"
}
}
}
Full TypeScript support with included type definitions:
// src/types.ts (provided by library)
import { IpcResponse, ipcRequest, subscribeToStreamingTask } from './types';
interface User {
id: string;
name: string;
email: string;
}
// Type-safe requests
const user = await ipcRequest<User>('ipc://user/123');
console.log(user.name); // TypeScript knows this exists!
// Type-safe streaming
subscribeToStreamingTask(taskId, {
onProgress: (progress) => {
console.log(`${progress.percent}%`);
},
onComplete: (result) => {
console.log('Done!');
}
});
Create custom hooks for common patterns:
// useIpcQuery.ts
import { useState, useEffect } from 'react';
import { ipcRequest } from './types';
export function useIpcQuery<T>(url: string) {
const [data, setData] = useState<T | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
ipcRequest<T>(url)
.then(setData)
.catch(setError)
.finally(() => setLoading(false));
}, [url]);
return { data, loading, error };
}
// Usage
function UserProfile({ userId }: { userId: string }) {
const { data: user, loading } = useIpcQuery<User>(`ipc://user/${userId}`);
if (loading) return <div>Loading...</div>;
return <div>{user?.name}</div>;
}
Develop React app with hot reload:
npm run dev
Build for production:
npm run build
Copy to Dioxus assets:
cp dist/assets/index-*.js ../dioxus-app/assets/react/bundle.js
Run Dioxus app:
cargo run
#!/bin/bash
# build-react.sh
cd react-app
npm run build
# Copy bundle to Dioxus assets
cp dist/assets/index-*.js ../dioxus-app/assets/react/bundle.js
echo "React app built and copied to Dioxus assets!"
Optimize your Vite build for Dioxus integration:
// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
build: {
rollupOptions: {
output: {
// Single bundle file
entryFileNames: 'bundle.js',
chunkFileNames: 'bundle.js',
assetFileNames: 'assets/[name].[ext]'
}
}
}
});
Recommended project structure:
my-app/
├── Cargo.toml
├── src/
│ └── main.rs # Dioxus app
├── assets/
│ └── react/
│ └── bundle.js # Built React bundle
└── react-app/ # React source
├── package.json
├── src/
│ ├── App.tsx
│ └── types.ts # IPC type definitions
└── vite.config.ts
See the examples/ directory for complete working examples:
simple_react.rs - Basic React integrationwith_assets.rs - Using asset registryfull_app/ - Complete example applicationRun an example:
cargo run --example simple_react --features desktop
ReactContainer: Dioxus component for mounting React apps
bundle: Asset - React bundle assetmount_id: String - DOM element ID for mountingasset-registry: Enable dynamic asset loading systemDioxusBridge: Main bridge interfaceIpcResponse<T>: Response typeIpcRequestOptions: Request configurationStreamingProgress: Progress updatesipcRequest<T>(url): Helper for type-safe requestssubscribeToStreamingTask(): Subscribe to streaming events| Platform | Status | Notes |
|---|---|---|
| Desktop | ✅ Fully Supported | Native window with webview |
| Web | ✅ Fully Supported | WASM + JavaScript |
| Mobile | ✅ Fully Supported | Native webview on iOS/Android |
npm run build)try {
const data = await ipcRequest('ipc://api/endpoint');
} catch (error) {
console.error('IPC request failed:', error);
// Show user-friendly error message
}
npm run build)window.dioxusBridge exists in browser consoletypes.ts is copied to React projectContributions are welcome! Please feel free to submit a Pull Request.
Licensed under either of:
at your option.