Preact
The @nano_kit/preact package integrates @nano_kit/store signals and Dependency Injection with Preact components.
Installation
Section titled “Installation”Install the package using your favorite package manager:
pnpm add @nano_kit/store @nano_kit/preactyarn add @nano_kit/store @nano_kit/preactnpm install @nano_kit/store @nano_kit/preactSignals
Section titled “Signals”useSignal
Section titled “useSignal”The useSignal hook subscribes a Preact component to any accessor. The component will re-render automatically whenever the value changes.
import { signal } from '@nano_kit/store'import { useSignal } from '@nano_kit/preact'
const $count = signal(0)
export function Counter() { const count = useSignal($count)
return ( <button onClick={() => $count(count => count + 1)}> Count: {count} </button> )}Dependency Injection
Section titled “Dependency Injection”InjectionContextProvider
Section titled “InjectionContextProvider”To use the Dependency Injection system within Preact, wrap your application (or part of it) in InjectionContextProvider. This component initializes an InjectionContext and makes it available to child components via the Preact Context API.
You can provide an existing context instance or an array of providers/values.
import { provide } from '@nano_kit/store'import { InjectionContextProvider } from '@nano_kit/preact'import { Theme$ } from './tokens'import { App } from './App'
function Root() { return ( <InjectionContextProvider context={[ provide(Theme$, 'dark') ]} > <App /> </InjectionContextProvider> )}useInject
Section titled “useInject”The useInject hook retrieves a dependency from the current injection context. It throws an error if the context is missing, ensuring your dependencies are always resolved.
import { useInject } from '@nano_kit/preact'import { Theme$ } from './tokens'
export function ThemedButton() { const theme = useInject(Theme$)
return <button className={`btn-${theme}`}>Click me</button>}injectHook
Section titled “injectHook”injectHook creates a reusable hook for a given injection token. This is useful for encapsulating injection logic away from components.
import { injectHook } from '@nano_kit/preact'
/* Define token */function Theme$(): 'light' | 'dark' { return 'light'}
/* Create custom hook */const useTheme = injectHook(Theme$)
export function ThemedButton() { const theme = useTheme() // Type-safe 'light' | 'dark'
return <button className={`btn-${theme}`}>Click me</button>}signalHook
Section titled “signalHook”signalHook creates a hook that subscribes to a signal returned by a getter function. Useful for wrapping signal-valued injection tokens into stable hooks.
import { signalHook, injectHook } from '@nano_kit/preact'import { Location$ } from '@nano_kit/router'
/* Creates a hook that reads and subscribes to the location signal */const useLocation = signalHook(injectHook(Location$))
export function ActiveLink({ route }) { const location = useLocation() /* ... */}Isolate
Section titled “Isolate”Isolate renders children with a fresh injection boundary. Use it when a subtree must not inherit dependencies from the parent context.
import { Isolate } from '@nano_kit/preact'
export function Preview({ children }) { return ( <Isolate> {children} </Isolate> )}Client-Side Hydration
Section titled “Client-Side Hydration”HydrationProvider
Section titled “HydrationProvider”HydrationProvider sets up a reactive hydration context for client-side hydration. It uses ActiveHydrator under the hood, which supports streaming — the dehydrated prop can be updated on re-renders to feed new data.
import { HydrationProvider } from '@nano_kit/preact'
function App({ dehydrated }) { return ( <HydrationProvider dehydrated={dehydrated}> <UserProfile /> </HydrationProvider> )}Props:
dehydrated?— dehydrated key-value pairs[string, unknown][], or a falsy value to skip hydrationcontext?— additional injection providersreuse?— reuse an existingInjectionContextinstead of creating a new one; set totrueif you want the hydration context to be shared with the rest of your app instead of isolated
StaticHydrationProvider
Section titled “StaticHydrationProvider”StaticHydrationProvider is a simpler one-shot variant using StaticHydrator. It applies the initial dehydrated snapshot once and never updates. Use this for classic SSR where the full snapshot is available at first render.
import { StaticHydrationProvider } from '@nano_kit/preact'
function App({ dehydrated }) { return ( <StaticHydrationProvider dehydrated={dehydrated}> <UserProfile /> </StaticHydrationProvider> )}