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

nude-reactivity

v0.0.1

Published

A minimal, zero dependency signal library, intended to be used in Web Components abstractions.

Readme

Nude Reactivity

A minimal, zero dependency signal library, intended to be used in Web Components abstractions.

Seriously, another one?

Most signals libraries were designed for frameworks and made it hard to use them to develop custom elements that work like native ones.

Design principles:

  • DX as a priority
  • Flexibility for consumers over encapsulation
  • Lightweight core with abstractions layered on top

Resulting design:

  • Sync & eager by default; you only opt into async or lazy where it can't be observed otherwise
  • Cycle detection with smart handling of self-writes to avoid false positives
  • Glitch-free: no intermediate states, no "stale" values
  • Flexible computed write policy (override, ignore, throw)
  • Pluggable equality, so you control what counts as a change
  • No build step: pure ESM you can import straight from source

Install

npm install nude-reactivity
import { signal, computed, effect, watch, reactive } from "nude-reactivity";

Sync by default

No microtasks, no promises to juggle, no ticks.

Meaning, this just works:

import { signal, computed } from "nude-reactivity";
const a = signal(1);
const b = computed(() => a.value + 1);
a.value++;
console.log(b.value); // 3

Reactive objects

reactive() makes a plain object reactive in place: data properties become signals, getters become computeds. Consumers just touch plain properties — no .value, no framework.

import { reactive } from "nude-reactivity";

const state = reactive({
	count: 1,
	get double () {
		return this.count * 2;
	},
});

state.count++;
console.log(state.double); // 4

Writing a getter-only property is governed by the computedWrites option ("ignore" by default, or "override" / "throw").

Effects and watchers

effect() runs a function and re-runs it whenever its reactive dependencies change. It returns a teardown function that stops it:

const stop = effect(() => console.log(a.value));
a.value++; // logs
stop(); // no more re-runs

watch() is like effect(), but pausable: the function it returns pauses the effect and itself returns a resume function, so you can toggle it on and off.

const pause = watch(() => console.log(a.value));
const resume = pause(); // detached: changes are ignored
resume(); // re-runs and re-tracks dependencies

API

| Export | Description | | ------------------------- | ----------------------------------------------------------------------------------------------------------------------- | | signal(value) | A writable reactive value, read/written via .value. | | computed(fn, options?) | A derived value. options.lazy opts into pull-based (recompute on read); options.equals customizes change detection. | | effect(fn) | Runs fn, re-running on dependency changes. Returns a teardown function. | | watch(fn) | Like effect(), but the returned function pauses and resumes. | | reactive(obj, options?) | Makes an object's properties reactive in place. | | ReactiveNode (default) | The low-level node all of the above are built on. |

The library is layered, and each layer is independently importable: nude-reactivity/node (core), nude-reactivity/reactive (objects), nude-reactivity/shortcuts (signal/computed/effect/watch).

Roadmap

  • [ ] Track oldValue
  • [ ] Better self-write handling
  • [ ] Batched microtask updates
  • [ ] Async computeds/effects
  • [ ] Reactive class