ethanbarlo/livewiremesh
LivewireMesh integrates React components directly into Laravel Livewire using Livewire hooks (no Alpine intermediary). Get reactive props, two-way binding via useEntangle (live or deferred), and direct access to Livewire methods/properties with useWire.
Installation:
composer require ethanbarlo/livewiremesh
Follow the INSTALL.md guide to configure Vite/TypeScript or manual Livewire bundling.
First Mesh Component:
MeshComponent in your Livewire class:
use EthanBarlo\LivewireMesh\MeshComponent;
class Counter extends MeshComponent {
public int $count = 0;
public function component(): string {
return 'resources/js/components/Counter.tsx';
}
}
import { useEntangle } from '@livewiremesh/react/contexts/LivewireContext';
export const Counter = () => {
const [count, setCount] = useEntangle<number>('count');
return (
<button onClick={() => setCount(count + 1)}>
Count: {count}
</button>
);
};
Render the Component:
<livewire:counter />
Replace a standard Livewire input with a React-powered component:
// Livewire Component
class UserForm extends MeshComponent {
public string $name = '';
public function component(): string {
return 'resources/js/components/UserInput.tsx';
}
}
// React Component
const UserInput = () => {
const [name, setName] = useEntangle<string>('name');
return <input value={name} onChange={(e) => setName(e.target.value)} />;
};
<!-- Blade View -->
<livewire:user-form wire:model="name" />
Use useEntangle for reactive Livewire properties:
const [value, setValue] = useEntangle<string>('property_name');
// Updates Livewire when `setValue` is called, and React when Livewire updates.
Live/Deferred Updates:
wire:model.live in Blade for deferred updates (e.g., for performance-heavy components).Use the useWire hook to call Livewire methods from React:
const $wire = useWire();
const handleClick = () => $wire.call('increment');
Leverage useErrorBag for validation feedback:
const errors = useErrorBag();
return <ErrorMessage error={errors['name']} />;
Pass props from Livewire to React:
// Livewire
public function props(): array {
return ['options' => $this->getOptions()];
}
// React
interface Props {
options: string[];
}
const Component = ({ options }: Props) => { ... };
Use Livewire’s wire:key or React’s key prop to manage component lifecycle:
<livewire:mesh-component wire:key="dynamic-key" />
Mesh components work seamlessly in modals (e.g., wire:modal):
<button wire:click="$toggle('modal')">Open Modal</button>
<livewire:mesh-modal wire:model="isOpen" />
Define types for props and entangled values:
interface User {
id: number;
name: string;
}
const [user, setUser] = useEntangle<User>('user');
Asset Loading Race Conditions:
wire:key or ensure the component’s component() path is static. Dynamic asset loading (v0.6.1+) resolves this.Duplicate Render Calls:
Caching Quirks:
mesh-*.blade.php) may cache stale versions.MeshComponent::getMeshViewPath() manually.TypeScript Generics:
useEntangle may cause type inference errors.useEntangle<number>('count')).Enable Debug Logs:
Add to config/livewiremesh.php:
'debug' => env('APP_DEBUG', false),
Logs asset loading and hook execution.
Check Asset Paths:
Verify the component() path in MeshComponent matches your React entry file.
Validate Hook Usage:
Ensure useEntangle, useWire, and useErrorBag are called within a Mesh component’s React context.
Custom Hooks:
Extend the package by adding hooks to @livewiremesh/react/contexts/LivewireContext.
Global Config:
Override defaults in config/livewiremesh.php:
'asset_loader' => 'vite', // or 'laravel-mix'
'react_context' => 'LivewireContext',
Livewire 4+ Compatibility:
Use #[Modelable] for property binding (v0.6.0+):
#[Modelable]
public string $name;
Performance Optimization:
wire:model.live for deferred updates in large datasets.React.lazy.maxRenderAttempts and renderDelay (v0.6.1+) are ignored but accepted for backward compatibility..tsx files. Example Vite config:
// vite.config.ts
export default defineConfig({
build: {
rollupOptions: {
input: {
'resources/js/app.tsx': './resources/js/app.tsx',
// Add Mesh component entry points
'resources/js/components/MeshComponent.tsx': './resources/js/components/MeshComponent.tsx',
},
},
},
});
How can I help you explore Laravel packages today?