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

@stealthscale/settings

v0.1.0

Published

Remembers one named setting a person made, per application, held to the values it is allowed to take and kept where the reader chooses.

Readme

@stealthscale/settings

@stealthscale/settings remembers one named value a person chose. A setting is kept per application, so two applications on one origin keep their own. Where it is kept is part of its definition rather than of a call, so one setting reads the same on a server and in a browser.

The value is read from the store on each render rather than copied into state. Every reader of one setting therefore reads one value, in this tab and in every other. A tab somebody left open cannot overwrite a choice they made somewhere else, because it holds no stale copy to write back.

Install

pnpm add @stealthscale/settings

The package peers on react and nothing else.

Defining a setting

A setting states its name, the values it may take, and what it returns until a person chooses. The fallback is stated apart from the values, so a colour mode that follows the machine until somebody overrides it states both without repeating either.

import { defineSetting } from "@stealthscale/settings";

export const colorMode = defineSetting({
  fallback: "system",
  name: "color-mode",
  values: ["light", "dark"],
});

Reading it in a component

import { useSetting } from "@stealthscale/settings";

export function ColorModeToggle({ app }: { app: string }) {
  const [mode, setMode] = useSetting(app, colorMode);

  return <button onClick={() => setMode(mode === "dark" ? "light" : "dark")}>{mode}</button>;
}

The application's name is passed in rather than read from a context, because the server and any inline script have to name the same application and neither of those has React around it.

Reading it without React

readSetting, writeSetting and clearSetting take the same definition and no hook. A server handling a request uses them, and so does the script an application inlines to settle its first paint.

import { cookieStore, defineSetting, readSetting } from "@stealthscale/settings";

const mode = readSetting("docs", colorMode);

The three stores

| Store | Kept in | Read by the server | Visible in another tab | | --------------- | ------------------ | ------------------ | ----------------------------------------------------- | | localStore() | The page's storage | No | At once, through storage | | cookieStore() | A cookie | Yes | At once, where the browser ships the Cookie Store API | | memoryStore() | The process | Not applicable | Not applicable |

localStore() is what a setting uses where it names no store, and it is right for anything the page decides after it has drawn.

cookieStore() is for a setting that decides the first paint. A cookie is the one place a setting is visible to the server, so the first response already carries the remembered value and no script has to correct the page after it paints. On a server, build the store from the request:

const store = cookieStore({ header: request.headers.get("cookie") ?? "" });

export const theme = defineSetting({ fallback: "fathom", name: "theme", store, values: THEMES });

The cost is that a cookie is sent on every request and shares a four-kilobyte budget per origin. Reading is synchronous, through document.cookie, because a snapshot is read during a render. The Cookie Store API reports a change, so a write in another tab updates this one where the browser has shipped that interface. It reached Baseline in June 2025 and needs a secure context. Where it is absent, a cookie changed elsewhere arrives on the next load.

memoryStore() holds settings for as long as the process runs. Each call builds a store of its own, which is what makes it right for a specification: one case never reads what another wrote.

The inline script

A person who has never chosen gets the right first paint from CSS alone, because the theme foundation's conditions follow the operating system where the page writes no attribute. The flash only happens when a stored choice disagrees with the machine.

A server-rendered application solves that with a cookie and renders the attribute itself. A static single-page application has no server to personalise the document, so it still needs a blocking script in the head. That script reads the key settingKey writes and nothing else from this package.

Reference

| Export | Signature | | --------------- | ------------------------------------------------------------------------------- | | defineSetting | <Value>(options: SettingOptions<Value>) => SettingDefinition<Value> | | settingKey | (app: string, name: string) => string | | readSetting | <Value>(app: string, setting: SettingDefinition<Value>) => Value | | writeSetting | <Value>(app: string, setting: SettingDefinition<Value>, value: Value) => void | | clearSetting | <Value>(app: string, setting: SettingDefinition<Value>) => void | | useSetting | <Value>(app, setting) => readonly [Value, (value: Value) => void] | | localStore | () => SettingStore | | cookieStore | (options?: CookieStoreOptions) => SettingStore | | memoryStore | (initial?: Readonly<Record<string, string>>) => SettingStore | | watchers | () => Watchers |

Writing a store

A store is read, written, cleared and subscribed to. The browser's own Storage interface has no notification, which is why a setting built on it alone cannot report one tab's choice to another. Requiring subscribe on every store makes notification part of the contract.

export interface SettingStore {
  clear: (key: string) => void;
  read: (key: string) => null | string;
  subscribe: (key: string, onChange: () => void) => () => void;
  write: (key: string, value: string) => void;
}

watchers() builds the set of callbacks a store calls when one of its keys changes. A store needs one because the browser raises no event in the document that made the change, so a write would otherwise update every other tab and not the one the person is looking at.

Licence

MIT. See LICENSE.