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 🙏

© 2025 – Pkg Stats / Ryan Hefner

rcrx

v0.0.4

Published

Rcrx is a lightweight library that provides Rx.js utilities for React applications.

Readme

Rcrx

Lightweight RxJS hooks for React. 简洁的 React + RxJS Hook 工具库。

Overview

Rcrx provides a minimal set of hooks to seamlessly use RxJS Observables within React components:

  • useObservable — read the latest value from an Observable as React state
  • useSubscribe — subscribe to an Observable and map each emission using your function

Designed to be tiny, typed, and easy to adopt.

Features

  • Minimal API, zero configuration
  • Automatic subscription management (unsubscribe on unmount)
  • TypeScript support with generics
  • Works with any RxJS Observable
  • Keeps subscription stable when the mapping function changes (via ref)

Installation

Using your favorite package manager:

# pnpm
pnpm add rcrx rxjs

# npm
npm install rcrx rxjs

# yarn
yarn add rcrx rxjs

Peer requirements:

  • react >= 16.8.0 (hooks)
  • rxjs (any 7+ recommended)

Quick Start

useObservable

import { useObservable } from "rcrx";
import { Observable } from "rxjs";

const counter$ = new Observable<number>((subscriber) => {
  let n = 0;
  const id = setInterval(() => subscriber.next(n++), 1000);
  return () => clearInterval(id);
});

function Counter() {
  const n = useObservable(counter$);
  return <div>{n}</div>;
}

useSubscribe

import { useSubscribe } from "rcrx";
import { Observable } from "rxjs";
import { useState } from "react";

const counter$ = new Observable<number>((subscriber) => {
  let n = 0;
  const id = setInterval(() => subscriber.next(n++), 1000);
  return () => clearInterval(id);
});

function Counter() {
  const [n, setN] = useState(0);
  useSubscribe(counter$, (v) => setN(v));
  return <div>{n}</div>;
}

API

useObservable(observable: Observable): T | undefined

  • Subscribes to the provided observable when the component mounts and returns the latest emitted value.
  • Re-subscribes if the observable instance changes.
  • Returns undefined until the first value is emitted.

useSubscribe<TValue, TReturnValue>(

observable: Observable, fn: (value: TValue) => TReturnValue, defaultReturnValue?: TReturnValue ): TReturnValue | undefined

  • Subscribes to the observable and applies fn to each emission; the hook returns the latest mapped result.
  • Keeps the same subscription even if fn changes (fn is stored in a ref).
  • Re-subscribes if the observable instance changes.
  • Returns defaultReturnValue initially (or undefined if omitted).

Notes:

  • For side-effects only, ignore the return value and use fn to update component state.
  • For derived state, return a mapped value from fn and read the hook's return value.

Advanced Usage

Switching Observables

function Dynamic({ source }: { source: Observable<number> }) {
  const value = useObservable(source);
  return <div>{value}</div>;
}

When the source prop changes to a different Observable instance, the hook will unsubscribe from the previous one and subscribe to the new one.

Mapping Without Re-subscribing

function Mapped({ source }: { source: Observable<number> }) {
  const doubled = useSubscribe(source, (v) => v * 2, 0);
  return <div>{doubled}</div>;
}

Changing the mapping function identity won’t cause a re-subscription; only the Observable instance identity matters.

TypeScript

  • Fully typed generics for both hooks
  • No additional TS configuration required

Development

  • Build: pnpm build (outputs to dist/ via tsup)
  • Test: pnpm test or pnpm test:watch (Vitest)

License

ISC


中文说明

Rcrx 提供一组极简的 React + RxJS Hook,帮助你在 React 组件中无缝使用 RxJS Observable:

  • useObservable —— 将 Observable 的最新值作为组件状态读取
  • useSubscribe —— 订阅 Observable,并用你的函数映射每次推送

特性

  • API 极简、开箱即用
  • 自动管理订阅(组件卸载自动取消订阅)
  • 完整的 TypeScript 支持
  • 适配任意 RxJS Observable
  • 当映射函数变更时保持订阅稳定(通过 ref)

安装

# pnpm
pnpm add rcrx rxjs

# npm
npm install rcrx rxjs

# yarn
yarn add rcrx rxjs

对等依赖与推荐:

  • react >= 16.8.0(支持 Hook)
  • rxjs(建议 7+)

快速上手

useObservable

import { useObservable } from "rcrx";
import { Observable } from "rxjs";

const counter$ = new Observable<number>((subscriber) => {
  let n = 0;
  const id = setInterval(() => subscriber.next(n++), 1000);
  return () => clearInterval(id);
});

function Counter() {
  const n = useObservable(counter$);
  return <div>{n}</div>;
}

useSubscribe

import { useSubscribe } from "rcrx";
import { Observable } from "rxjs";
import { useState } from "react";

const counter$ = new Observable<number>((subscriber) => {
  let n = 0;
  const id = setInterval(() => subscriber.next(n++), 1000);
  return () => clearInterval(id);
});

function Counter() {
  const [n, setN] = useState(0);
  useSubscribe(counter$, (v) => setN(v));
  return <div>{n}</div>;
}

API 说明

useObservable(observable: Observable): T | undefined

  • 组件挂载时订阅 Observable,并返回其最新推送值;当 Observable 实例变化时自动重新订阅。
  • 在首次推送之前返回 undefined。

useSubscribe<TValue, TReturnValue>(

observable: Observable, fn: (value: TValue) => TReturnValue, defaultReturnValue?: TReturnValue ): TReturnValue | undefined

  • 订阅 Observable,并对每次推送应用 fn;Hook 返回最近一次映射的结果。
  • fn 变更不会触发重新订阅(内部通过 ref 保存最新 fn)。
  • 当 Observable 实例变化时会重新订阅。
  • 初始返回 defaultReturnValue(未传入则为 undefined)。

提示:

  • 仅用于副作用时,可忽略返回值,直接在 fn 中 setState。
  • 需要派生状态时,可在 fn 中返回映射值,并通过 Hook 的返回值读取。

进阶用法

切换 Observable

function Dynamic({ source }: { source: Observable<number> }) {
  const value = useObservable(source);
  return <div>{value}</div>;
}

当 source 属性切换为新的 Observable 实例时,Hook 会自动取消之前的订阅,并订阅到新的实例。

映射但不重新订阅

function Mapped({ source }: { source: Observable<number> }) {
  const doubled = useSubscribe(source, (v) => v * 2, 0);
  return <div>{doubled}</div>;
}

映射函数的引用发生变化不会触发重新订阅;只有 Observable 实例变化时才会。

本地开发

  • 构建:pnpm build(使用 tsup 输出到 dist/
  • 测试:pnpm testpnpm test:watch(Vitest)

许可证

MIT