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

@tempots/client

v0.0.4

Published

Client-side hydration utilities for Tempo SSR applications

Readme

@tempots/client

Client-side hydration utilities for Tempo applications with SSR support.

Installation

npm install @tempots/client
# or
pnpm add @tempots/client

Features

  • Hydration: Attach client-side interactivity to server-rendered HTML
  • Islands Architecture: Partial hydration with lazy loading strategies
  • Multiple Hydration Strategies: immediate, idle, visible, and media query-based
  • Full Tempo Compatibility: Works seamlessly with Tempo signals and components

Usage

Quick Start with startClient()

The simplest way to initialize your client-side application:

// entry-client.ts
import { startClient } from '@tempots/client'
import { App, Counter, TodoList } from './app'

startClient({
  app: () => App(),              // App to render in client-only mode
  islands: { Counter, TodoList }, // Islands to hydrate
  debug: true,                    // Optional: enable debug logging
})

startClient() automatically:

  • Detects SSR vs client-only mode
  • Initializes islands with their hydration strategies
  • Sets up HMR cleanup (when available)

Basic Hydration (Low-Level)

For more control, use the low-level hydrate() function:

import { hydrate } from '@tempots/client'
import { App } from './App'

// Server-rendered HTML is already in the DOM
const container = document.getElementById('app')!

// Hydrate with client-side interactivity
const cleanup = hydrate(App(), container)

// Later, to cleanup all event listeners:
cleanup()

Islands Architecture

Islands allow you to hydrate only specific interactive components while keeping the rest as static HTML.

Server-side: Mark islands

import { html } from '@tempots/dom'
import {
  ISLAND_ATTR,
  ISLAND_OPTIONS_ATTR,
  ISLAND_HYDRATE_ATTR,
} from '@tempots/client'

// Or use the islandMarker helper
import { islandMarker } from '@tempots/client'

const Page = () => html.div(
  html.h1('Static content - no JS shipped'),

  // This counter will be hydrated as an island
  html.div(
    ...islandMarker('Counter', { initial: 10 }, 'visible'),
    // Server-rendered content
    html.button('-'),
    html.span('10'),
    html.button('+'),
  ),
)

Client-side: Initialize islands

import { initIslands } from '@tempots/client'
import { Counter } from './islands/Counter'

// Initialize all islands found in the document
const cleanup = initIslands({
  Counter,
})

Hydration Strategies

Islands support multiple hydration strategies to optimize loading performance:

// Hydrate immediately when JS loads
islandMarker('Counter', options, 'immediate')

// Hydrate when browser is idle (requestIdleCallback)
islandMarker('Counter', options, 'idle')

// Hydrate when scrolled into view (IntersectionObserver)
islandMarker('Counter', options, 'visible')

// Hydrate when media query matches
islandMarker('Counter', options, { media: '(min-width: 768px)' })

API

startClient(options)

High-level function to initialize the Tempo client with automatic SSR detection.

Options:

  • app?: () => Renderable - App component for client-only rendering
  • islands: IslandRegistry - Map of island names to component factories
  • container?: string | HTMLElement - Container selector or element (default: "#app")
  • providers?: Providers - Providers to inject during hydration
  • debug?: boolean - Enable debug logging (default: false)

Returns: () => void - Cleanup function

Example:

startClient({
  app: () => App(),
  islands: { Counter, TodoList },
  container: '#app',
  debug: true,
})

hydrate(renderable, container, options?)

Hydrates server-rendered HTML with client-side interactivity.

Parameters:

  • renderable: Renderable - The Tempo renderable (should match server render)
  • container: HTMLElement - Container with server-rendered content
  • options?: HydrateOptions - Optional configuration

Options:

  • providers?: Providers - Providers to inject during hydration
  • removeMarkers?: boolean - Remove hydration markers after hydration (default: true)

Returns: () => void - Cleanup function

hydrateIsland(element, component, componentOptions, hydrateOptions?)

Hydrates a single island element.

Parameters:

  • element: HTMLElement - The island container element
  • component: (options: O) => Renderable - Component factory
  • componentOptions: O - Options to pass to the component
  • hydrateOptions?: IslandHydrateOptions - Optional configuration

Returns: () => void - Cleanup function

initIslands(registry, options?)

Scans the document for islands and hydrates them based on their strategy.

Parameters:

  • registry: IslandRegistry - Map of island names to component factories
  • options?: IslandHydrateOptions - Optional configuration

Returns: () => void - Cleanup function for all islands

islandMarker(name, options, strategy?)

Creates attributes for marking an island during server-side rendering.

Parameters:

  • name: string - Island name (must match registry key)
  • options: unknown - Options to serialize
  • strategy?: HydrationStrategy - When to hydrate (default: 'visible')

Returns: Array<{ name: string; value: string }> - Attribute list

Constants

  • ISLAND_ATTR - Attribute name for island markers (data-tempo-island)
  • ISLAND_HYDRATE_ATTR - Attribute for hydration strategy (data-tempo-hydrate)
  • ISLAND_OPTIONS_ATTR - Attribute for serialized options (data-tempo-options)
  • HYDRATION_ID_ATTR - Attribute for hydration IDs (data-tts-id)

License

Apache-2.0