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

@vobs/preferences

v1.8.18

Published

Schema-validated, persisted user preferences exposed as typed reactive signals.

Readme

@vobs/preferences

Schema-validated, persisted user preferences exposed as typed reactive signals.

Install

npm install @vobs/preferences

Quick start

import { createPreferences, definePreferences } from '@vobs/preferences'

const schema = definePreferences({
  theme: { type: 'string', default: 'light', validate: value => value === 'light' || value === 'dark' },
  pageSize: { type: 'number', default: 20 }
})

const preferences = createPreferences({
  preferences: schema,
  storage: 'memory',
  saveDebounce: 100
})

preferences.set('theme', 'dark')
preferences.theme.value // 'dark' — every schema key is also a Signal
preferences.get('pageSize') // 20
preferences.reset('theme')

API

| Signature | Description | | --- | --- | | definePreferences(schema: S): S | Validates a schema at creation; every entry needs a default, optional type, and optional validate. | | createPreferences(options: PreferencesOptions<S>): PreferencesContext<S> | Creates a context; restores stored values immediately and starts auto-save unless autoSave: false. | | preferences.[key]: Signal | Each schema key is exposed as a typed signal on the context. | | preferences.get(key) / preferences.set(key, value) | Reads or writes one preference; set validates against the schema. | | preferences.reset(key) / preferences.resetAll() | Restores defaults for one key or the whole schema. | | preferences.restore(): void | Re-reads storage, validates entries, and reports invalid ones via onError; also cancels any pending debounced save. | | preferences.save(): void | Persists all values with a version envelope; throws PreferenceError('PERSIST_FAILED') on failure. | | preferences.subscribe(listener): () => void | Receives { key, value, source } for local, external, and restore changes. | | preferences.dispose(): void | Stops effects, timers, and the storage subscription. | | preferencesPlugin(options): VobsPlugin | Provides the context through PREFERENCES_KEY. | | usePreferences<S>(): PreferencesContext<S> | Injects the preferences context inside components. |

Values are checked against the schema type and optional validate predicate; set with an invalid value throws PreferenceError('INVALID_VALUE'), while invalid stored values fall back to defaults and are reported. Auto-save (on by default) persists schema values with optional saveDebounce; version plus migrate upgrades old payloads; userSpecific with getUserId re-restores when the user changes; external storage changes are picked up through the storage subscription.

restore() writes the restored values through resetAll(), so its own writes are marked as restore writes and keep the pending auto-save suppressed for that flush. Two consequences are worth knowing at the call site. A real set() in the same synchronous task still persists: it clears that suppression, so restore(); set('pageSize', 99) ends with 99 on disk instead of silently keeping the stored value. And because a restore makes memory follow storage, a debounced save that was already queued is dropped — otherwise that stale snapshot would be written back after an external removeItem() and resurrect a key another tab just deleted.

Types

PreferenceSchema, PreferenceDefinition, PreferenceType, PreferenceValue, PreferenceSignals, PreferenceChange, PreferencesContext, PreferencesOptions, PreferencesPluginOptions, PreferenceErrorCode