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

birpc-x

v0.0.9

Published

Extensible birpc interfaces

Readme

birpc-x

npm version npm downloads bundle JSDocs License

Extensible birpc interfaces.

[!IMPORTANT] Experimental. API may change anytime.

Features

On top of birpc, birpc-x adds the following features:

  • Type-safe function definitions
  • Dynamically registerable functions
  • User-provided function context
  • Schema-validation via valibot
  • Cache Manager for RPC results

Installation

ppm install birpc-x

Usage

Defining Functions

Use defineRpcFunction to create type-safe RPC function definitions:

import { defineRpcFunction } from 'birpc-x'

// Simple function
const greet = defineRpcFunction({
  name: 'greet',
  handler: (name: string) => `Hello, ${name}!`
})

On top of birpc, birpc-x also provides a standardize way to provide a context to the function.

import { defineRpcFunction } from 'birpc-x'

// With setup and context
const getUser = defineRpcFunction({
  name: 'getUser',
  setup: (context) => {
    console.log(context)
    return {
      handler: (id: string) => context.users[id]
    }
  }
})

Schema Validation

Use Valibot schemas for automatic argument and return value validation:

import * as v from 'valibot'

const add = defineRpcFunction({
  name: 'add',
  args: [v.number(), v.number()] as const,
  returns: v.number(),
  handler: (a, b) => a + b // Types are automatically inferred
})

Function Collector

RpcFunctionsCollector manages dynamic function registration and provides a type-safe proxy for accessing functions:

import { RpcFunctionsCollectorBase } from 'birpc-x'

// Provide a custom context to the collector
const collector = new RpcFunctionsCollectorBase({ users: [/* ... */] })

// Register functions
collector.register(defineRpcFunction({
  name: 'greet',
  handler: (name: string) => `Hello, ${name}!`,
}))
collector.register(defineRpcFunction({
  name: 'getUser',
  setup: (context) => {
    return {
      handler: (id: string) => context.users.find((user: { id: string }) => user.id === id)
    }
  }
}))

// Access via proxy
await collector.functions.greet('Alice') // "Hello, Alice!"

// Listen for changes
const unsubscribe = collector.onChanged((fnName) => {
  console.log(`Function ${fnName} changed`)
})

Dump Feature

The dump feature allows pre-computing RPC results for static hosting, testing, or offline mode. This is useful for static sites or when you want to avoid runtime computation.

import { createClientFromDump, dumpFunctions } from 'birpc-x'

// Define functions with dump configurations
const greet = defineRpcFunction({
  name: 'greet',
  handler: (name: string) => `Hello, ${name}!`,
  dump: {
    inputs: [
      ['Alice'],
      ['Bob'],
      ['Charlie']
    ],
    fallback: 'Hello, stranger!'
  }
})

// Collect pre-computed results
const store = await dumpFunctions([greet])

// Create a client that serves from the dump store
const client = createClientFromDump(store)

await client.greet('Alice') // Returns pre-computed: "Hello, Alice!"
await client.greet('Unknown') // Returns fallback: "Hello, stranger!"

Functions with type: 'static' automatically get dumped with empty arguments if no dump configuration is provided.

Pre-computed Records

You can provide pre-computed records directly to bypass function execution:

const multiply = defineRpcFunction({
  name: 'multiply',
  handler: (a: number, b: number) => a * b,
  dump: {
    records: [
      { inputs: [2, 3], output: 6 },
      { inputs: [4, 5], output: 20 },
    ],
  },
})

You can also mix computed (inputs) and pre-computed (records) in the same dump configuration.

Parallel Execution

Enable parallel processing for faster dump collection:

// Enable parallel with default concurrency of 5
const store = await dumpFunctions([greet], context, {
  concurrency: true
})

// Or specify a custom concurrency limit
const store = await dumpFunctions([greet], context, {
  concurrency: 10, // Limit to 10 concurrent executions
  onProgress: (completed, total, name) => {
    console.log(`${name}: ${completed}/${total}`)
  }
})

Set concurrency to true for parallel execution (default limit: 5) or a number to specify the exact concurrency limit.

Examples

See test directory for complete integration examples.

API Reference

Full API documentation available at jsdocs.io.

Sponsors

License

MIT License © Anthony Fu