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

vike-islands

v0.1.7

Published

Vike plugin for islands architecture — supports Vue and React

Downloads

1,049

Readme

vike-islands

Islands architecture for Vike. Supports Vue and React.

Keep pages fully SSR-only and hydrate only the components you explicitly mark as islands.

  • No full-page framework hydration
  • Mark any component as an island with ?island on the import
  • Client bootstrap injected only when the page actually contains islands
  • Framework runtime loaded lazily on first island hydration
  • Each framework ships its own adapter — only the one you use is bundled

Vue Setup · React Setup · Hydration Modes · SSR Caching · Manual Hydration · How It Works


Framework Support

| Framework | Status | |-----------|--------| | Vue | ✅ Stable | | React | ✅ Stable | | Solid | Planned |

Installation

pnpm add vike-islands
# or
npm install vike-islands

Vue Setup

Dependencies: vike, vike-vue, vue, vite, @vitejs/plugin-vue

1. Vite plugin

// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vike from 'vike/plugin'
import { vikeIslands } from 'vike-islands/vue'

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

2. Vike config

// pages/+config.ts
import type { Config } from 'vike/types'
import vikeVue from 'vike-vue/config'
import vikeIslands from 'vike-islands/vue/+config'

export default {
  extends: [vikeVue, vikeIslands],
  clientRouting: false,
  meta: {
    Page: {
      env: { server: true, client: false },
    },
  },
} satisfies Config

clientRouting: false and Page.env.client = false keep the page shell SSR-only.

3. Use a component as an island

Add ?island to the import — no need to rename or modify the component file:

<!-- pages/index/+Page.vue -->
<script setup lang="ts">
import Counter from '@/components/Counter.vue?island'
</script>

<template>
  <div>
    <h1>My page</h1>
    <Counter client:load :initial-count="0" label="My island" />
  </div>
</template>

TypeScript types for ?island imports are included automatically — no env.d.ts needed.


React Setup

Dependencies: vike, vike-react, react, react-dom, vite, @vitejs/plugin-react

1. Vite plugin

// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import vike from 'vike/plugin'
import { vikeIslands } from 'vike-islands/react'

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

2. Vike config

// pages/+config.ts
import type { Config } from 'vike/types'
import vikeReact from 'vike-react/config'
import vikeIslands from 'vike-islands/react/+config'

export default {
  extends: [vikeReact, vikeIslands],
  clientRouting: false,
  meta: {
    Page: {
      env: { server: true, client: false },
    },
  },
} satisfies Config

3. Use a component as an island

Same ?island import — the plugin transforms JSX automatically:

// pages/index/+Page.tsx
import Counter from '@/components/Counter?island'

export default function Page() {
  return (
    <div>
      <h1>My page</h1>
      <Counter client:load initialCount={0} label="My island" />
    </div>
  )
}

Hydration Modes

Controls when the island hydrates on the client.

| Mode | Behavior | |------|----------| | load | Immediately on page load | | idle | When the browser is idle (requestIdleCallback) | | visible | When the island scrolls into the viewport | | interaction | On first click, focus, or pointer enter | | manual | Only when triggered via hydrateIslandById() | | never | Never — stays as static SSR HTML |

Default: visible.

Vue

<Counter client:load />
<Counter client:visible />
<Counter client:idle />
<Counter client:interaction />
<Counter client:never />

React

<Counter client:load />
<Counter client:visible />
<Counter client:interaction />
<Counter client:never />

SSR Caching

Cache the SSR HTML of an island on the first render and serve it from cache on subsequent requests. The cache key is derived from the island name and its props.

Useful for expensive SSR sections that rarely change — product lists, article bodies, navigation trees.

Setup

Install the LMDB adapter (or bring your own):

pnpm add lmdb
// vite.config.ts
import { vikeIslands } from 'vike-islands/vue' // or 'vike-islands/react'
import { createLmdbCache } from 'vike-islands/cache/lmdb'

export default defineConfig({
  plugins: [
    vikeIslands({ cache: createLmdbCache() }),
    // ...
  ],
})

Vue

server:cache-key is required when using server:cache — it defines the cache key explicitly, avoiding expensive serialization of large props.

<!-- SSR-only, cached 9999 seconds -->
<ProductList client:never server:cache="9999" server:cache-key="products-spain" />

<!-- hydrated on load, cached 60 seconds -->
<ProductCard client:load server:cache="60" server:cache-key="card-42" :product="product" />

React

<ProductList client:never server:cache={9999} server:cache-key="products-spain" />
<ProductCard client:load server:cache={60} server:cache-key="card-42" product={product} />

Custom adapter

import type { IslandCacheAdapter } from 'vike-islands/cache/lmdb'

const myAdapter: IslandCacheAdapter = {
  async get(key) {
    return redis.get(key)
  },
  async set(key, html, ttl) {
    await redis.set(key, html, { EX: ttl })
  },
}

vikeIslands({ cache: myAdapter })

Manual Hydration

For hydrate: 'manual' islands, trigger hydration from your own code:

// Vue
import { hydrateIslandById } from 'vike-islands/vue'
await hydrateIslandById('i1')

// React
import { hydrateIslandById } from 'vike-islands/react'
await hydrateIslandById('i1')

The island id is assigned automatically by the transform (i1, i2, …).


Examples

pnpm run example:vue
pnpm run example:react

How It Works

  1. The Vite plugin scans the project for ?island imports at build time.
  2. Each island gets its own bundle entry — loaded only if the page uses it.
  3. The framework runtime (Vue / React) gets a separate bundle — shared across islands.
  4. On SSR, onRenderHtml detects which islands appear in the rendered HTML.
  5. If any islands are present, a small inline <script type="module"> is injected that:
    • Reads the island map from window.__VIKE_ISLANDS__
    • Imports the framework runtime lazily
    • Schedules each island for hydration according to its strategy
  6. Islands hydrate independently — no coordination with a page-level app.