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

@j4ndrw/fgr-core

v1.0.11

Published

The core library that provides primitives for fine-grained reactive systems

Readme

Fine-Grained Reactivity primitives

Inspired by SolidJS and Leptos.

Important

Please, don't use this library in production. For the moment, it is purely experimental and might not scale.

Installation

NPM

npm install @j4ndrw/fgr-core

Yarn

yarn add @j4ndrw/fgr-core

PNPM

pnpm add @j4ndrw/fgr-core

ESM.SH

<html>
    ...
    <body>
        <script type="module">
            import encapsulate from "https://esm.sh/@j4ndrw/fgr-core";
        </script>
    </body>
</html>

UNPKG

<html>
    ...
    <body>
        <script type="module">
            import encapsulate from "https://unpkg.com/@j4ndrw/fgr-core/dist/index.mjs";
        </script>
    </body>
</html>

Objective

The goal of this library is to inject fine grained reactivity to any non-reactive system, as well as existing reactive systems (i.e. React, Vue, etc...). It is a bit ambitious and it's not there yet when it comes to making the primitives work in existing reactive systems, but it would be super cool to learn about what obstacles need to be overcome to achieve this goal.

After looking through Solid and Leptos, I formed an opinion that fine-grained reactivity is the most elegant and efficient paradigm / concept when it comes to building UIs, games or any other state machine!

Overview

The library provides only 1 function: encapsulate. You can think of this function as a glorified IIFE (Immediately-Invoked Function Expression).

Simple counter example

Here's an example of a counter using the encapsulate function:

import { encapsulate } from "@j4ndrw/fgr-core";

encapsulate(({ signal, effect }) => {
    const count = signal(0);

    effect(() => {
        console.log(`Count is ${count.get()}`);
    });

    for (let i = 1; i <= 5; i++) {
        count.set(i);
    }
});

This will just iterate 5 times and increment the count signal by 1. In the console, you should see a bunch of "Count is {count}", thanks to the effect.

Batch counter example

Here's the same counter example as before, but with 2 count signals, instead of one.

import { encapsulate } from "@j4ndrw/fgr-core";

encapsulate(({ signal, effect, batch }) => {
    const count1 = signal(0);
    const count2 = signal(0);

    effect(() => {
        console.log(`Count1 is ${count1.get()}`);
        console.log(`Count2 is ${count2.get()}`);
    });

    for (let i = 1; i <= 5; i++) {
        batch(() => {
            count1.set(i);
            count2.set(i * 2);
        });
    }
});

Here we're using the batch primitive to postpone running the effect until the callback function inside the batch finishes running.

As such, the effect will run 5 times, instead of 10 times without the batch.

Docs

Encapsulate

Definition

A function that provides Fine-Grained Reactivity primitives inside the callback function it takes as an argument.

Example

import { encapsulate } from "@j4ndrw/fgr-core";

encapsulate(({ signal, effect, batch, unmount }, runtime) => {
    // Your business logic goes here
});

Signal

Definition

A primitive that holds a mutable value.

Example

const count = signal(0);
count.get(); // is 0

count.set(1);
count.get(); // is 1

count.update(prev => prev + 3);
count.get(); //is 4

Effect

Definition

A primitive that runs a given callback function on mount and whenever a dependency gets updated.

Example - Effect running once

effect(() => console.log("hello"));

Example - Effect running when dependency is updated

const dependency = signal(0);

// Outputs `hello ${dependency}` 6 times:
//     - 1 time on mount
//     - 5 times since the dependency is set 5 times
//       in the for loop below
effect(() => {
    console.log(`hello ${dependency.get()}`);
});

for (let i = 1; i <= 5; i++) dependency.set(i);

Batch

Definition

A primitive that postpones running any effects for a set of dependencies until they have finished running a particular routine.

Example - Without batch

const s1 = signal(0);
const s2 = signal(0);

// Runs 11 times:
//     - once, on mount
//     - 10 times, since `s1` is set 5 times and `s2`
//       is set 5 other times
effect(() => {
    s1.get();
    s2.get();
});

for (let i = 1; i <= 5; i++) {
    s1.set(i);
    s2.set(i);
}

Example - With batch

const s1 = signal(0);
const s2 = signal(0);

// Runs 6 times:
//     - once, on mount
//     - 5 times, from the batched update
effect(() => {
    s1.get();
    s2.get();
});

for (let i = 1; i <= 5; i++) {
    batch(() => {
        s1.set(i);
        s2.set(i);
    });
}

Unmount

Definition

A primitive that runs a cleanup function and re-initializes all primitive values from the Fine-Grained Reactivity Runtime (signals, effects, etc...).

Example

unmount(() => {
    // Cleanup logic goes here
});