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

@karpeleslab/react-klbfw-hooks

v0.4.3

Published

Various hooks for klbfw

Readme

React Hooks for KLBFW

A collection of React hooks and SSR utilities for KarpelesLab Framework.

Installation

npm install @karpeleslab/react-klbfw-hooks

Features

  • Shared state across components through named variables
  • SSR (Server-Side Rendering) with React
  • REST API integration with caching
  • React Router v7 support for modern routing with SSR
  • Promise handling for data loading during SSR

Available Hooks

  • useRest(path, params, noThrow, cacheLifeTime): Fetches data from your backend with automatic caching and SSR support
  • useVar(varName, defaultValue): Provides shared state accessible by name throughout your application
  • useVarSetter(varName, defaultValue): Returns only a setter for the given variable without subscribing to updates
  • usePromise(promise): Registers a promise for SSR to wait for before rendering
  • useRestRefresh(path, params, cacheLifeTime): Returns only the refresh function for a REST endpoint
  • useRestResetter(): Returns a function to clear all REST cache (useful for logout)

Usage

run(routes, promisesOrOptions, options)

The entry point function that replaces ReactDOM.render/hydrate with SSR support. Takes a route configuration and optional settings.

Parameters:

  • routes: A React Router route configuration created with createRoutesFromElements or directly as a route object
  • promisesOrOptions: Either an array of promises to wait for, or an options object
  • options: Configuration options (when using promises as the second parameter)

Options object properties:

  • routerProps: Additional props to pass to the Router component (useful for injecting stores or providers)
  • contextProps: Additional props to pass to the internal Context.Provider

Basic usage in your index.js:

import { run } from "@karpeleslab/react-klbfw-hooks";
import { Route, createRoutesFromElements } from "react-router-dom";
import Home from './routes/Home';

// Create routes with the Data Router API
const routes = createRoutesFromElements(
  <Route path="/" element={<Home />} />
);

// Pass the routes to run
run(routes);

Injecting additional props/providers:

import { run } from "@karpeleslab/react-klbfw-hooks";
import { Route, createRoutesFromElements } from "react-router-dom";
import { Provider } from 'react-redux';
import { store } from './store';
import Home from './routes/Home';

// Create routes
const routes = createRoutesFromElements(
  <Route path="/" element={<Home />} />
);

// Inject the Redux store by providing custom router props
run(routes, {
  routerProps: {
    // These props will be passed to the RouterProvider (client) or StaticRouterProvider (server)
    fallbackElement: <div>Loading...</div>,
    future: {
      v7_startTransition: true
    }
  },
  contextProps: {
    // You can also wrap the entire app with providers using React.createElement in your index.js
    // This is an alternative approach for global store/provider setup
  }
});

With React Router v7:

import { run } from "@karpeleslab/react-klbfw-hooks";
import { redirect, Route, createRoutesFromElements } from "react-router-dom";
import Home from './routes/Home';
import About from './routes/About';
import Contact from './routes/Contact';

// Create routes
const routes = createRoutesFromElements(
  <>
    <Route path="/" element={<Home />} />
    <Route path="/about" element={<About />} />
    <Route 
      path="/contact" 
      element={<Contact />} 
      loader={async () => {
        // Load data needed for this route
        const data = await fetch('/api/contact-info').then(r => r.json());
        return data;
      }}
    />
    <Route 
      path="/redirect" 
      loader={() => {
        // Redirect example with status code
        return redirect("/about", 301);
      }}
    />
  </>
);

// Pass routes to run
run(routes);

Server-Side Rendering with React Router v7

The library provides full support for React Router v7 SSR features including:

  • Data Loading: Routes with loaders will have their data pre-loaded during SSR
  • Redirects: Redirect responses from loaders are properly handled with status codes preserved
  • Data Router API: Uses the modern React Router v7 data APIs (createBrowserRouter, createStaticHandler, createStaticRouter, RouterProvider, StaticRouterProvider)

Under the hood, the implementation:

  1. On the client: Creates a browser router from routes using createBrowserRouter
  2. On the server: Creates a static handler from routes using createStaticHandler
  3. Processes routes with query function to detect redirects and load data
  4. Renders using createStaticRouter and StaticRouterProvider for SSR
  5. Preserves HTTP status codes (301, 302, etc.) for proper SEO

This allows you to use all modern React Router features while still benefiting from server-side rendering.

With i18n support:

import { run } from "@karpeleslab/react-klbfw-hooks";
import { Route } from "react-router-dom";
import Home from './routes/Home';
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import { Backend } from '@karpeleslab/i18next-klb-backend';
import { getLocale } from "@karpeleslab/klbfw";

let i18nOpt = {
	lng: getLocale(),
	initImmediate: false,
	load: 'currentOnly',
	interpolation: {
		escapeValue: false, // not needed for react as it escapes by default
	},
	react: {
		useSuspense: false,
	}
};

// Define your routes as an array of <Route> elements
const routes = [
  <Route path="/" element={<Home />} key="home" />
];

run(routes, [i18n.use(Backend).use(initReactI18next).init(i18nOpt)]);

useVar(varName, defaultValue)

Hook for creating/accessing named variables which share a value anywhere in the application.

function Counter() {
	const [count, setCount] = useVar("counter", 0);

	return (
		<div>
			Count is {count}
			<button onClick={() => setCount(count + 1)}>Increment</button>
		</div>
	);
}

In another component:

function DisplayCounter() {
	const [count] = useVar("counter", 0);
	return <div>Current count: {count}</div>;
}

useVarSetter(varName, defaultValue)

Returns only a setter for the given variable, without subscribing the current component to variable updates.

function CounterControl() {
	const setCount = useVarSetter("counter", 0);
	return <button onClick={() => setCount(0)}>Reset Counter</button>;
}

usePromise(promise)

Registers a promise that the server needs to wait for in SSR before rendering. Useful for ensuring data is available during server-side rendering.

function DataComponent() {
	const [data, setData] = useState(null);
	
	useEffect(() => {
		const promise = fetchData().then(result => setData(result));
		usePromise(promise);
	}, []);
	
	return <div>{data ? JSON.stringify(data) : "Loading..."}</div>;
}

useRest(path, params, noThrow, cacheLifeTime)

Performs a REST GET request to the specified path, caching the result and returning it in a way that is safe for rendering.

function UserProfile({ userId }) {
	const [user, refreshUser] = useRest(`/api/users/${userId}`);
	
	return (
		<div>
			{user ? (
				<>
					<h2>{user.name}</h2>
					<p>{user.email}</p>
					<button onClick={refreshUser}>Refresh</button>
				</>
			) : "Loading..."}
		</div>
	);
}

With parameters:

function SearchResults() {
	const [query, setQuery] = useState("");
	const [results, refreshResults] = useRest("/api/search", { q: query });
	
	return (
		<div>
			<input 
				value={query} 
				onChange={e => setQuery(e.target.value)} 
			/>
			<button onClick={refreshResults}>Search</button>
			
			{results && results.map(item => (
				<div key={item.id}>{item.title}</div>
			))}
		</div>
	);
}

License

MIT