Fixed: Alpine.js Not Initializing After Livewire Updates

The problem: After upgrading Livewire to v3, some Alpine.js components (x-data blocks, dropdowns, modals) stop initializing on pages that get updated by Livewire — they just sit there dead, no console error, no reaction to clicks.

Environment: Laravel 10/11, Livewire 3.x, Alpine.js 3.x installed separately via npm, Vite 5, resources/js/app.js bundling both.

The Error

Alpine Warning: Detected multiple instances of Alpine running

Alpine Warning: Alpine has already been initialized on this page.
Ignoring duplicate script tag/import.

You'll usually only see this if you have DevTools console open at the exact moment the page loads — after that, the components just look broken with no further logging.

Why It Happens

Since Livewire 3, Livewire ships its own bundled copy of Alpine.js internally. You don't need to install Alpine yourself anymore for Livewire to work — it's already inside livewire.js.

The problem is that most Laravel + Vite starter setups (and a lot of older tutorials) still have this in app.js:

resources/js/app.js
import Alpine from 'alpinejs';
window.Alpine = Alpine;
Alpine.start();

Now you have two separate Alpine instances running on the same page: Livewire's internal one, and your manually imported one. Whichever one starts second refuses to take over — so any Alpine component that Livewire's morph step touches (i.e. anything inside a Livewire component that re-renders) ends up bound to the "wrong" instance and never gets re-initialized after an update. That's why it looks like Alpine "randomly" stops working specifically after a Livewire update, and why static Alpine components outside any Livewire component keep working fine.

The Fix

Stop importing Alpine yourself. Let Livewire's bundled Alpine be the only instance on the page.

Remove this from app.js completely:

import Alpine from 'alpinejs';
window.Alpine = Alpine;
Alpine.start();

If you also register custom Alpine components with Alpine.data(), hook into Livewire's Alpine instance instead using the alpine:init event, which fires on the Alpine instance Livewire actually starts:

document.addEventListener('alpine:init', () => {
    Alpine.data('dropdown', () => ({
        open: false,
        toggle() {
            this.open = !this.open;
        }
    }));
});

Then make sure your Blade layout loads Livewire's assets (which bring Alpine along with them) and nothing else touches Alpine directly:

<head>
    @vite(['resources/css/app.css', 'resources/js/app.js'])
    @livewireStyles
</head>
<body>
    ...
    @livewireScripts
</body>

Run npm uninstall alpinejs if nothing else in your bundle needs it directly, so it can't accidentally get re-imported later.

Step-by-Step

  1. Open resources/js/app.js and delete any import Alpine from 'alpinejs', window.Alpine = Alpine, and Alpine.start() lines.
  2. Run npm uninstall alpinejs if no other JS in your project imports it directly.
  3. Move any Alpine.data(...), Alpine.store(...), or Alpine.directive(...) calls inside a document.addEventListener('alpine:init', () => { ... }) block.
  4. Confirm your Blade layout includes @livewireScripts before </body> and that it isn't duplicated on the page (check both your main layout and any partials).
  5. Rebuild assets with npm run build (or restart npm run dev) and hard-refresh with cache disabled.
  6. Open DevTools console on load — the "multiple instances" warning should be gone.
  7. Trigger a Livewire update (e.g. a wire:model change or wire:click) and confirm Alpine components inside that component still respond afterward.
Edge case: If you're using a package that bundles its own Alpine plugin (like some UI kits or admin panels), check whether that package also calls Alpine.start() internally. Two packages doing this independently will reproduce the exact same warning even after you've removed your own manual import — check node_modules for other alpinejs imports if the warning persists after step 1–3.

Still seeing this after checking your bundle? Reach out on the Contact page and I'll help you trace it.

Advertisement
Advertisement