npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

blade-islands

v0.1.1

Published

Blade islands for Laravel

Readme

🏝️ Blade Islands For Laravel

NPM Version NPM Downloads License

Client-side island runtime for Blade.

Blade Islands lets you render small React, Vue, or Svelte components inside Laravel Blade views without turning your application into a full single-page app.

This package provides the browser runtime. The Blade directives that render island placeholders live in the companion Laravel package eznix86/blade-islands.

Contents

Why Blade Islands?

Blade Islands works well when your application is mostly server-rendered but still needs interactive UI in places such as:

  • search inputs
  • dashboards
  • maps
  • counters
  • filters
  • dialogs

Instead of building entire pages in a frontend framework, you can keep Blade as your primary rendering layer and hydrate only the parts of the page that need JavaScript.

Installation

Install Blade Islands, your frontend framework, and the matching Vite plugin.

React

npm install blade-islands react react-dom @vitejs/plugin-react

Vue

npm install blade-islands vue @vitejs/plugin-vue

Svelte

npm install blade-islands svelte @sveltejs/vite-plugin-svelte

Quick Start

Add the runtime to resources/js/app.js, load that entry from your Blade layout, and render an island from Blade.

React

resources/js/app.js

import islands from 'blade-islands/react'

islands()

Blade layout:

<head>
    @viteReactRefresh
    @vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
@react('ProfileCard', ['user' => $user])

Resolves to resources/js/islands/ProfileCard.jsx.

Vue

resources/js/app.js

import islands from 'blade-islands/vue'

islands()

Blade layout:

<head>
    @vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
@vue('ProfileCard', ['user' => $user])

Resolves to resources/js/islands/ProfileCard.vue.

Svelte

resources/js/app.js

import islands from 'blade-islands/svelte'

islands()

Blade layout:

<head>
    @vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
@svelte('ProfileCard', ['user' => $user])

Resolves to resources/js/islands/ProfileCard.svelte.

How It Works

Blade Islands has two parts:

  • the Laravel package renders island placeholders from Blade
  • this package scans the DOM and mounts the matching frontend component

For example:

@react('Account/UsageChart', ['stats' => $stats])

mounts:

resources/js/islands/Account/UsageChart.jsx

Entry Points

Blade Islands provides framework-specific entry points:

import islands from 'blade-islands/react'
import islands from 'blade-islands/vue'
import islands from 'blade-islands/svelte'

Each entry point mounts only its own island type.

Vite Setup

Register the plugin for the framework you use.

React

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
  plugins: [react()],
})

If your Laravel layout loads a React entrypoint in development, include:

@viteReactRefresh

Vue

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [vue()],
})

Svelte

import { defineConfig } from 'vite'
import { svelte } from '@sveltejs/vite-plugin-svelte'

export default defineConfig({
  plugins: [svelte()],
})

Component Resolution

By default, Blade Islands looks for components in resources/js/islands.

Nested folders work automatically. For example:

@react('Billing/Invoices/Table', [...])
@vue('Billing/Invoices/Table', [...])
@svelte('Billing/Invoices/Table', [...])

These resolve to:

resources/js/islands/Billing/Invoices/Table.jsx
resources/js/islands/Billing/Invoices/Table.vue
resources/js/islands/Billing/Invoices/Table.svelte

Custom Root

If your components live outside the default root, pass both root and components:

import islands from 'blade-islands/vue'

islands({
  root: '/resources/js/widgets',
  components: import.meta.glob('/resources/js/widgets/**/*.vue'),
})

Then:

@vue('Dashboard', [...])

resolves to resources/js/widgets/Dashboard.vue.

Preserve Mounted Islands

Use preserve: true when the same DOM is processed more than once and you want Blade Islands to keep an existing island mounted instead of mounting it again.

This is useful when the page or a DOM fragment is recalculated and your frontend boot logic runs again.

@react('Dashboard/RevenueChart', ['stats' => $stats], preserve: true)
@vue('Dashboard/RevenueChart', ['stats' => $stats], preserve: true)
@svelte('Dashboard/RevenueChart', ['stats' => $stats], preserve: true)

If you reuse a preserved component in a loop, give each island a unique key on the Blade side so the runtime can distinguish them correctly:

@foreach ($products as $product)
    @react('Product/Card', ['product' => $product], preserve: true, key: "product-{$product->id}")
@endforeach

Options

Each entry point exports a default islands() function:

islands({
  root: '/resources/js/islands',
  components: import.meta.glob('/resources/js/islands/**/*.{jsx,tsx}'),
})
  • root - component root used to derive names such as Billing/Invoices/Table
  • components - Vite import.meta.glob(...) map for the current framework

Requirements

  • Vite
  • React 18+ for blade-islands/react
  • Vue 3+ for blade-islands/vue
  • Svelte 5+ for blade-islands/svelte

Companion Package

This runtime expects Blade placeholders generated by the Laravel package:

  • Composer package: eznix86/blade-islands
  • Repository: laravel-blade-islands

Blade Islands vs X

Inertia.js

Inertia is a better fit when your application wants React, Vue, or Svelte to render full pages with a JavaScript-first page architecture.

Blade Islands is a better fit when your application is already Blade-first and you want to keep server-rendered pages while hydrating only selected components.

MingleJS

MingleJS is often used in Laravel applications that embed React or Vue components, especially in Livewire-heavy codebases.

Blade Islands is more naturally suited to Blade-first applications that want progressive enhancement with minimal architectural change. It does not depend on Livewire, and it may also be used alongside Livewire when that fits your application.

Laravel UI

Laravel UI is a legacy scaffolding package for frontend presets and authentication views.

Blade Islands solves a different problem: adding targeted client-side interactivity to server-rendered Blade pages.

Testing

npm install
npm test

Contributing

Contributions are welcome.

  1. Fork the repository
  2. Create a focused branch
  3. Add or update tests
  4. Run npm test
  5. Open a pull request with a clear summary

License

MIT