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

@fluixi/reactive

v1.0.0-alpha.57

Published

Fine-grained reactive signals, memos, effects, stores and an RxJS-style observable layer.

Readme

@fluixi/reactive

Fine-grained reactive signals, memos, effects, stores and an RxJS-style observable layer.

License: MIT TypeScript npm Inspired by SolidJS


A powerful, fine-grained reactive system with SolidJS-inspired features for building high-performance applications.

Features

🎯 Core Reactivity

  • Signals - Fine-grained reactive primitives
  • Effects - Automatic dependency tracking
  • Memos - Cached computed values
  • Batch Updates - SolidJS-style batching with runUpdates()

⚡ Advanced Features

  • Priority-Based Scheduling - Optimal update ordering (RENDER → COMPUTE → EFFECT → TRANSITION)
  • Transitions - Non-blocking updates for better UX
  • Suspense Boundaries - Declarative async data loading
  • Error Boundaries - Graceful error handling
  • Context API - State sharing without prop drilling
  • Render Effects - Synchronous DOM updates
  • Reactions - Manual dependency tracking
  • Owner Management - Advanced lifecycle control

🔍 Developer Experience

  • Enhanced Debugging - Detailed warnings with dependency chains and performance metrics
  • Memory Leak Detection - Find potential issues early
  • Node Statistics - Monitor reactive graph performance
  • TypeScript - Full type safety and inference
  • RxJS Integration - Seamless Observable interop

Installation

npm install @fluixi/reactive

Quick Start

Basic Usage

import { createSignal, createEffect, createMemo, batch } from '@fluixi/reactive';

// Create reactive state
const [count, setCount] = createSignal(0);

// Derived state (cached)
const doubled = createMemo(() => count() * 2);

// Side effects (auto-tracking)
createEffect(() => {
  console.log(`Count: ${count()}, Doubled: ${doubled()}`);
});

// Update state
setCount(1); // Effect runs: "Count: 1, Doubled: 2"

// Batch multiple updates
batch(() => {
  setCount(2);
  setCount(3);
}); // Effect runs once: "Count: 3, Doubled: 6"

Advanced Usage

import {
  startTransition,
  useTransition,
  createSuspense,
  trackPromise,
  catchError,
  createContext,
  useContext
} from '@fluixi/reactive';

// Non-blocking updates
const [isPending, start] = useTransition();
start(() => {
  setLargeDataSet(expensiveComputation());
});

// Async data with suspense
const UserProfile = createSuspense(
  () => {
    const data = trackPromise(fetchUser(userId()));
    return <Profile data={data} />;
  },
  <ProfileSkeleton />
);

// Error handling
const safeData = catchError(
  () => parseData(input()),
  (error) => {
    console.error(error);
    return fallbackValue;
  }
);

// Context for state sharing
const ThemeContext = createContext({ mode: 'light' });
ThemeContext.Provider({
  value: { mode: 'dark' },
  children: () => <App />
});

// Consume context
const theme = useContext(ThemeContext);

Priority-Based Scheduling

Updates are processed in optimal order:

enum UpdatePriority {
  IMMEDIATE = 0,    // Immediate synchronous updates
  RENDER = 1,       // DOM updates (highest priority)
  COMPUTE = 2,      // Memos and computed values
  EFFECT = 3,       // Side effects
  TRANSITION = 4,   // Low-priority updates (lowest)
}

Batch & Update Queue

SolidJS-inspired batching with runUpdates():

batch(() => {
  setA(1);
  setB(2);
  setC(3);
}); // All effects run once in priority order

// Internal mechanism:
// 1. Updates queued in updateQueue
// 2. runUpdates() processes queue
// 3. Flushes in priority order: renders → computations → effects

Enhanced Debugging

Automatic warnings for performance issues:

⚠️ [Reactivity Warning] Coarse Dependency Detected

Node Information:
┌─────────────┬──────────────────┐
│ Node Name   │ userData         │
│ Observers   │ 18               │
└─────────────┴──────────────────┘

Reason:
  Reading large object (23 keys) - consider using 
  derived signals for specific properties

Performance Metrics:
┌───────────────────┬──────────┐
│ Updates           │ 45       │
│ Avg Frequency     │ 120ms    │
└───────────────────┴──────────┘

Suggestions:
  • Use derived signals for specific properties
  • Consider breaking into smaller signals

API Reference

Core API

  • createSignal(initialValue, options?) - Create reactive state
  • createEffect(fn, options?) - Run side effects
  • createMemo(fn, initialValue?, options?) - Create derived state
  • batch(fn) - Batch multiple updates
  • untrack(fn) - Read signals without tracking
  • createRoot(fn) - Create disposal root

Transitions

  • startTransition(fn) - Mark updates as low priority
  • useTransition() - Track transition state

Suspense

  • createSuspense(fn, fallback) - Create async boundary
  • trackPromise(promise) - Register promise with suspense

Error Handling

  • catchError(fn, handler) - Handle errors gracefully

Context

  • createContext(defaultValue) - Create context
  • useContext(context) - Consume context

Enhanced Effects

  • createRenderEffect(fn) - Synchronous DOM updates
  • createReaction(onInvalidate) - Manual dependency tracking
  • on(deps, fn, options?) - Explicit dependencies

Owner Management

  • getOwner() - Get current reactive owner
  • runWithOwner(owner, fn) - Run with specific owner

Debugging

  • warnCoarseRead(node, reason) - Enhanced warnings
  • getNodeStats() - Get reactive graph statistics
  • findPotentialLeaks() - Find memory leaks
  • enableDevMode() - Enable dev mode features

Utilities

  • createEnhancedSignal(initialValue) - Signal with extras
  • createAsyncSignal(asyncFn) - Async signal
  • createLazySignal(fn) - Lazy-evaluated signal
  • createSignalWithHistory(initialValue) - Signal with undo/redo
  • createThrottledSignal(signal, delay) - Throttled updates
  • createDebouncedSignal(signal, delay) - Debounced updates
  • createTrigger() - Manual trigger
  • createSelector(source, fn) - Keyed selector
  • createResource(fetcher, source?) - Async resource
  • createStore(initialValue) - Nested reactive object

Documentation

Complete documentation available at:

What's New (v3.2.0+)

Major Enhancements

Priority-Based Scheduling - Updates execute in optimal order
SolidJS-Style Batching - New runUpdates() mechanism
Transitions API - Non-blocking updates with startTransition()
Suspense Boundaries - Declarative async with createSuspense()
Error Boundaries - Graceful error handling with catchError()
Context API - State sharing with createContext()
Enhanced Debugging - Detailed warnings and performance metrics
Transition State Tracking - Automatic priority in computations

Breaking Changes

None! All enhancements are 100% backward compatible.

Performance Tips

  1. Use transitions for expensive updates

    startTransition(() => setLargeList(compute()));
  2. Batch related updates

    batch(() => { setA(1); setB(2); });
  3. Use memos for expensive computations

    const result = createMemo(() => expensive(signal()));
  4. Leverage suspense for async

    createSuspense(() => trackPromise(fetch()), <Loading />);
  5. Monitor with debugging tools

    const stats = getNodeStats();
    const leaks = findPotentialLeaks();

Best Practices

✅ Do

  • Use batch() for multiple related updates
  • Use startTransition() for non-urgent updates
  • Add error boundaries with catchError()
  • Use context instead of prop drilling
  • Monitor performance with debugging tools

❌ Don't

  • Update signals without batching when multiple updates needed
  • Block UI with expensive synchronous computations
  • Ignore errors in reactive code
  • Prop drill when context would work better

Building

nx build reactive

Running Tests

nx test reactive

License

MIT

Credits

Inspired by:

  • SolidJS - Reactivity primitives and scheduling
  • React - Transitions and Suspense concepts
  • Vue 3 - Reactivity system design

Version: 3.2.0+
Status: ✅ Production Ready