Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Livewiremesh Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require ethanbarlo/livewiremesh
    

    Follow the INSTALL.md guide to configure Vite/TypeScript or manual Livewire bundling.

  2. First Mesh Component:

    • Extend 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';
          }
      }
      
    • Create a React component at the specified path:
      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>
          );
      };
      
  3. Render the Component:

    <livewire:counter />
    

First Use Case: Reactive Form Input

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" />

Implementation Patterns

1. Two-Way Data Binding

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:

  • Default: Live updates (real-time sync).
  • Use wire:model.live in Blade for deferred updates (e.g., for performance-heavy components).

2. Accessing Livewire Methods

Use the useWire hook to call Livewire methods from React:

const $wire = useWire();
const handleClick = () => $wire.call('increment');

3. Validation Error Handling

Leverage useErrorBag for validation feedback:

const errors = useErrorBag();
return <ErrorMessage error={errors['name']} />;

4. Dynamic Props

Pass props from Livewire to React:

// Livewire
public function props(): array {
    return ['options' => $this->getOptions()];
}
// React
interface Props {
    options: string[];
}
const Component = ({ options }: Props) => { ... };

5. Conditional Rendering

Use Livewire’s wire:key or React’s key prop to manage component lifecycle:

<livewire:mesh-component wire:key="dynamic-key" />

6. Integration with Livewire Modals

Mesh components work seamlessly in modals (e.g., wire:modal):

<button wire:click="$toggle('modal')">Open Modal</button>
<livewire:mesh-modal wire:model="isOpen" />

7. TypeScript Support

Define types for props and entangled values:

interface User {
    id: number;
    name: string;
}
const [user, setUser] = useEntangle<User>('user');

Gotchas and Tips

Pitfalls

  1. Asset Loading Race Conditions:

    • Issue: Mesh components in modals or dynamically rendered sections may fail to load assets on first render.
    • Fix: Use wire:key or ensure the component’s component() path is static. Dynamic asset loading (v0.6.1+) resolves this.
  2. Duplicate Render Calls:

    • Issue: Unmount errors from duplicate renders (fixed in v0.5.3).
    • Fix: Avoid re-rendering the same component with identical props/keys.
  3. Caching Quirks:

    • Issue: Blade views (mesh-*.blade.php) may cache stale versions.
    • Fix: Clear cached views or update MeshComponent::getMeshViewPath() manually.
  4. TypeScript Generics:

    • Issue: Forgetting generics in useEntangle may cause type inference errors.
    • Fix: Always specify types (e.g., useEntangle<number>('count')).

Debugging Tips

  1. Enable Debug Logs: Add to config/livewiremesh.php:

    'debug' => env('APP_DEBUG', false),
    

    Logs asset loading and hook execution.

  2. Check Asset Paths: Verify the component() path in MeshComponent matches your React entry file.

  3. Validate Hook Usage: Ensure useEntangle, useWire, and useErrorBag are called within a Mesh component’s React context.


Extension Points

  1. Custom Hooks: Extend the package by adding hooks to @livewiremesh/react/contexts/LivewireContext.

  2. Global Config: Override defaults in config/livewiremesh.php:

    'asset_loader' => 'vite', // or 'laravel-mix'
    'react_context' => 'LivewireContext',
    
  3. Livewire 4+ Compatibility: Use #[Modelable] for property binding (v0.6.0+):

    #[Modelable]
    public string $name;
    
  4. Performance Optimization:

    • Use wire:model.live for deferred updates in large datasets.
    • Lazy-load heavy React components with React.lazy.

Config Quirks

  • Deprecated Configs: maxRenderAttempts and renderDelay (v0.6.1+) are ignored but accepted for backward compatibility.
  • Asset Loader: Ensure your build tool (Vite/Mix) processes .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',
                },
            },
        },
    });
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi