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

@11ty/is-land

v5.0.1

Published

A framework independent partial hydration islands architecture implementation.

Readme

<is-land>

A new performance-focused way to add interactive client-side components to your web site.

Or, more technically: a framework independent partial hydration islands architecture implementation.

Features:

  • Easy to add to existing components
  • Zero dependencies
  • Not tightly coupled to a server framework or site generator tool.
  • Small footprint (1.79 kB compressed)
  • Server-rendered (SSR) component examples available for SSR-friendly frameworks (Lit, Svelte, Vue, Preact are provided)

Examples for:

Integrations in the wild: Eleventy, WebC, Slinkity, SvelteKit, Bridgetown, Lit

Installation

Available on npm at @11ty/is-land.

npm install @11ty/is-land
<script type="module" src="/is-land.js"></script>

Add is-land.js to your primary bundle.

It can be deferred and/or loaded asynchronously. When using with web components it must be loaded before any other custom elements (via customElements.define) on the page. Choose your style:

Usage

<is-land>This is an island.</is-land>

Add any number of loading conditions to this tag to control how and when the island is initialized. You can mix and match. All conditions be satisfied to initialize.

  • on:visible
  • on:load (new in v5)
  • on:idle
  • on:interaction (defaults to touchstart,click)
    • Change events with on:interaction="mouseenter,focusin"
  • on:media
    • When Viewport size matches: on:media="(min-width: 64em)"
    • Reduced motion:
      • When user prefers reduced motion on:media="(prefers-reduced-motion)"
      • When user has no preference on motion on:media="(prefers-reduced-motion: no-preference)"
  • Save Data (read about Save Data on MDN)
    • When Save Data is active on:save-data
    • When Save Data is inactive on:save-data="false"
<is-land on:visible on:idle>
  <!-- your HTML here -->

  <is-land on:media="(min-width: 64em)">
    <!-- Islands can be nested -->
    <!-- Islands inherit all of their parents’ loading conditions -->
  </is-land>
</is-land>

Controlling Fallback Content

Pre-JS

<is-land on:visible on:idle>
  <vanilla-web-component>
    Put your pre-JS fallback content in your web component.
  </vanilla-web-component>
</is-land>

Post-JS with <template>

Place any post-JS content inside of one or more <template data-island> elements anywhere in the <is-land>. These will be swapped with their template content. You can nest an <is-land> in there if you want!

<is-land on:visible on:idle>
  <template data-island>
    <vanilla-web-component>
      This component is post-JS.
    </vanilla-web-component>
  </template>
</is-land>
  • Use data-island="replace" to replace the contents of the <is-land> with the template.
  • Use data-island="once" to run a template’s contents once per page (keyed from template contents). (New in v2.0.1)

Run your own custom JavaScript, load your own CSS

Embed a script inside the template to run custom JS when the island’s loading conditions have been satisfied!

<is-land on:visible>
  <template data-island>
    <!-- CSS -->
    <style>/* My custom CSS */</style>
    <link rel="stylesheet" href="my-css-file.css">

    <!-- JS -->
    <script type="module">console.log("Hydrating!");</script>
    <script type="module" src="my-js-file.js"></script>
  </template>
</is-land>

You can also use the ready attribute for styling, added to the <is-land> when the island has been hydrated.

<style>
is-land[ready] {
  background-color: lightgreen;
}
</style>

Framework Component Support

  • type: initialize a framework initialization type, registered by you. Examples included for: alpine, petite-vue, vue, vue-ssr, preact, preact-ssr, svelte, or svelte-ssr.

Demos, examples, and source code are available for each framework listed here.

Petite Vue

  • Examples
  • Small library (~9K)
  • Rendering modes: Client
  • Progressive-enhancement friendly (control fallback content)
<script type="module">
// Define once for any number of Petite Vue islands.
Island.addInitType("petite-vue", async (target) => {
	const { createApp } = await import("https://unpkg.com/[email protected]/dist/petite-vue.es.js");
	createApp().mount(target);
});
</script>
<is-land on:visible type="petite-vue" v-scope="{ name: 'Vue' }">
  Hello from <span v-html="name">HTML</span>
</is-land>

Vue

  • Examples
  • Larger library (~73 kB)
  • Rendering modes: Client (shown), Server, Server + Client (Hydration)
<script type="module">
// Define once for any number of Vue islands.
Island.addInitType("vue", async (target) => {
	const { createApp } = await import("https://unpkg.com/[email protected]/dist/vue.esm-browser.js");
	createApp({
		data: () => (target.dataset), // use <is-land data-> attributes as component data
	}).mount(target);
});
</script>
<is-land on:visible type="vue" data-name="Vue">
	Hello from <span v-text="name"></span>
</is-land>

Svelte

  • Examples (using Import Maps)
  • Medium-sized library
  • Rendering modes: Client, Server, Server + Client (Hydration)
  • Requires a compiler for client mode (uncommon)
<script type="module">
// Define once for any number of Svelte islands.
Island.addInitType("svelte", async (target) => {
	// requires an Import map and svelte is lazy loaded when island is ready
	const { mount } = await import("svelte");
	const component = await import(target.getAttribute("import"));

	mount(component.default, {
		target: target,
		props: {},
	});
});
</script>
<!-- This example uses an Eleventy `svelte` Universal Filter (see SveltePlugin.cjs) -->
{% assign component = "./lib/svelte/my-component-js-only.svelte" | svelte %}
<is-land on:visible type="svelte" import="{{ component.clientJsUrl }}"></is-land>
<!-- importmap from https://generator.jspm.io/ -->
<script type="importmap">
{
	"imports": {
		"svelte": "https://unpkg.com/[email protected]/src/index-client.js",
		"svelte/internal/client": "https://unpkg.com/[email protected]/src/internal/client/index.js",
		"svelte/internal/flags/legacy": "https://unpkg.com/[email protected]/src/internal/flags/legacy.js"
	},
	"scopes": {
		"https://unpkg.com/": {
			"clsx": "https://unpkg.com/[email protected]/dist/clsx.mjs",
			"esm-env": "https://unpkg.com/[email protected]/index.js",
			"esm-env/browser": "https://unpkg.com/[email protected]/true.js",
			"esm-env/development": "https://unpkg.com/[email protected]/false.js",
			"esm-env/node": "https://unpkg.com/[email protected]/false.js"
		}
	}
}
</script>

Preact

  • Examples
  • Small library (~9 kB)
  • Rendering modes: Client (shown), Server, Server + Client (Hydration)
  • No compiler needed when using htm rather than JSX.
<script type="module">
// Define once for any number of Preact islands.
Island.addInitType("preact", async (target) => {
	const component = await import(target.getAttribute("import"));
	component.default(target);
});
</script>
<is-land on:visible type="preact" import="preact-component.js"></is-land>
import { html, render } from 'https://unpkg.com/htm/preact/index.mjs?module'

function App (props) {
  return html`<p><strong>Hello ${props.name}!</strong></p>`;
}

export default function(el) {
  render(html`<${App} name="from Preact" />`, el);
}

Lit

  • Examples (using Import Maps)
  • Small library (~10 kB)
  • Rendering modes: Client, Server, Server + Client (Hydration)
<is-land on:visible import="lit-component.js">
  <lit-component name="Post-JS">Pre-JS Content</lit-web-component>
</is-land>
<!-- importmap from https://generator.jspm.io/ -->
<script type="importmap">
{
	"imports": {
		"lit": "https://unpkg.com/[email protected]/index.js"
	},
	"scopes": {
		"https://unpkg.com/": {
			"@lit/reactive-element": "https://unpkg.com/@lit/[email protected]/reactive-element.js",
			"lit-element/lit-element.js": "https://unpkg.com/[email protected]/lit-element.js",
			"lit-html": "https://unpkg.com/[email protected]/lit-html.js",
			"lit-html/is-server.js": "https://unpkg.com/[email protected]/is-server.js"
		}
	}
}
</script>
import {html, css, LitElement} from "lit";

customElements.define('lit-component', class extends LitElement {
  static properties = {
    name: {type: String},
  };

  render() {
    return html`<p>Hello, ${this.name || "Stranger"}!</p>`;
  }
});

Alpine.js

  • Examples
  • Smaller library (~20 kB)
  • Rendering modes: Client
  • Progressive-enhancement friendly (control fallback content)
<script type="module">
// Define once for any number of Alpine islands.
Island.addInitType("alpine", async (target) => {
	await import("https://unpkg.com/[email protected]/dist/cdn.min.js");
});

// Workaround for Alpine global mount
Island.addFallback("[x-data]", (node) => {
  if(node.hasAttribute("x-ignore")) {
    return;
  }

  node.setAttribute("x-ignore", "");

  return () => {
    node.removeAttribute("x-ignore");

    if(Alpine) {
      Alpine.nextTick(() => Alpine.initTree(node));
    }
  };
});
</script>
<is-land on:visible type="alpine">
  <div x-data="{ name: 'Alpine.js' }">
    Hello from <span x-text="name">HTML</span>!
  </div>
</is-land>

Solid.js

  • Examples (using Import Maps)
  • Medium library (~40 kB)
  • Rendering modes: Client