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

derivation

v0.6.0

Published

Core graph and streaming infrastructure for incremental computation

Readme

Derivation

This is a work in progress. Don't use this for anything you care about yet.

A simple TypeScript library for building incremental and reactive dataflow systems.

🚀 Installation

npm install derivation

🕒 Global Time and Coordination

Unlike other reactive frameworks, derivation uses a global time that advances in discrete steps. This means that, if you want to look at two values, you don't need to worry about whether only one of them has updated, because they are all kept in lock-step and they are updated in topological order (dependencies before dependents).

const graph = new Graph();
const a = graph.inputValue(0);
const b = graph.inputValue(1);

const derived = a.zip(b, (x, y) => x + y);

// We need to hold a reference to the sink so that it doesn't get garbage collected
const sink = derived.sink((x) => console.log(x)); // outputs 1

a.push(7);
b.push(3);

// Pushing values doesn't trigger a global step. Only calling step will do that.
graph.step(); // outputs 10

🧹 Lifecycle

ReactiveValues are references to underlying streams. These references can be explicitly disposed of with .dispose(), otherwise they'll be disposed of when they are GC'd.

When an underlying stream has no more references, it'll stop being computed when it has no more references, either within the computation graph, or via ReactiveValue references.

✨ Types

This package contains one kind of reactive thing:

  • ReactiveValue<T> is the type for things that update all at once. This is useful for primitive types like strings and numbers, but, more importantly, these are the building blocks on which more interesting types of reactive things can be built.

🔧 Operators

ReactiveValue provides several operators for combining and transforming values:

  • map(f) - transform values: ReactiveValue<A>ReactiveValue<B>
  • zip(other, f) - combine two values: ReactiveValue<A>, ReactiveValue<B>ReactiveValue<C>
  • accumulate(initial, f) - fold over time with state
  • delay(initial) - delay by one step
  • bind(f) - dynamic switch: ReactiveValue<A>, A -> ReactiveValue<B>ReactiveValue<B>. bind takes ownership of wrappers returned by f and disposes old/current wrappers as it switches/tears down. The callback must return a fresh ReactiveValue wrapper on each invocation (for example x.clone()).
  • sink(f) - observe values (side effects)

🔄 Dynamic Graph Construction

You can dynamically construct reactive values during a step, but you must ensure that the values that you create only depend on values that have already been processed in the current step.