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

@budarin/json-rpc-api-provider

v1.2.10

Published

A lightweight, zero-configuration TypeScript library that transforms your interface definitions into fully-typed JSON-RPC API clients. No code generation, no boilerplate—just pure Proxy magic.

Readme

json-rpc-api-provider

A lightweight, zero-configuration TypeScript library that transforms your interface definitions into fully-typed JSON-RPC API clients. No code generation, no boilerplate—just pure Proxy magic.

Elegant, type-safe JSON-RPC API provider with automatic camelCase to snake_case conversion

npm version License: MIT

✨ Features

  • 🎯 Full Type Safety - Complete TypeScript support with type inference for requests and responses
  • 🔄 Smart Name Conversion - Automatic camelCase → snake_case transformation for method names
  • 📦 Lightweight - Minimal footprint with only essential dependencies
  • 🎭 Proxy-Based Magic - No code generation or build step required
  • 🆔 Flexible ID Generation - Bring your own UUID generator (UUID v4, v7, nanoid, etc.)
  • ✨ Clean API - Write idiomatic JavaScript/TypeScript, let the library handle JSON-RPC protocol details
  • 🔒 Immutable by Design - Deep readonly types ensure request integrity

📦 Installation

# npm
npm install @budarin/json-rpc-api-provider

# pnpm
pnpm add @budarin/json-rpc-api-provider

# yarn
yarn add @budarin/json-rpc-api-provider

🚀 Quick Start

import { uuidv7 } from 'uuidv7';
import { createRequest } from '@budarin/json-rpc-request';
import { createApiProvider, type JsonRpcResponse } from '@budarin/json-rpc-api-provider';

// Define your API interface
interface TodoAPI {
    getTodo: (id: string) => Promise<JsonRpcResponse<Todo>>;
    createTodo: (todo: NewTodo) => Promise<JsonRpcResponse<Todo>>;
    updateTodo: (id: string, updates: Partial<Todo>) => Promise<JsonRpcResponse<Todo>>;
    deleteTodo: (id: string) => Promise<JsonRpcResponse<void>>;
}

// Create request
const request = createRequest('/api');

// Create your API provider
const api = createApiProvider<TodoAPI>(request, uuidv7);

// Use it with full type safety
const { result, error } = await api.getTodo('123');
//     ^? { result?: Todo; error?: JsonRpcError }

💡 Why Use This?

Before: Manual JSON-RPC Calls

// Repetitive, error-prone, no type safety
const response = await fetch('/api', {
    method: 'POST',
    body: JSON.stringify({
        jsonrpc: '2.0',
        id: generateId(),
        method: 'get_todo', // Easy to mistype
        params: { id: todoId },
    }),
});
const data = await response.json();
// No type checking on response
if (data.error) {
    /* ... */
}

After: With json-rpc-api-provider

// Clean, type-safe, idiomatic
const { result, error } = await api.getTodo(todoId);
//     ^? Fully typed!
if (error) {
    /* TypeScript knows the error shape */
}

Multiple API Providers

// Separate providers for different services
const userApi = createApiProvider<UserAPI>(createRequest('/api/users'), uuidv7);
const todoApi = createApiProvider<TodoAPI>(createRequest('/api/todos'), uuidv7);
const authApi = createApiProvider<AuthAPI>(createRequest('/api/auth'), uuidv7);

// Use them independently
await userApi.getUser('123');
await todoApi.getTodo('456');
await authApi.login({ username, password });

🎯 Method Name Conversion

The library automatically converts your camelCase method names to snake_case for JSON-RPC:

| JavaScript/TypeScript | JSON-RPC Method | | --------------------- | ------------------ | | getTodo() | get_todo | | createTodo() | create_todo | | getUserProfile() | get_user_profile | | updateAPIKey() | update_api_key | | deleteOldData() | delete_old_data |

This allows you to write idiomatic JavaScript/TypeScript while adhering to JSON-RPC naming conventions.

📚 API Reference

createApiProvider<T>(request, uuidGenerator)

Creates a type-safe proxy object that converts method calls into JSON-RPC requests.

Parameters

  • request: Request (from @budarin/json-rpc-api-provider)

    • A function that handles HTTP communication
    • Must accept a Request object with a body property
    • Should return a Promise<JsonRpcResponse<T, E>>
  • uuidGenerator: () => string

    • A function that generates unique identifiers for each request
    • Called once per API method invocation
    • Common choices: uuidv4, uuidv7, nanoid, or custom implementations

Returns

  • DeepReadonly<T>: A proxy object with methods matching your API interface
    • All methods are deeply immutable to prevent accidental modifications
    • Each method call automatically:
      • Generates a unique ID using uuidGenerator
      • Converts the method name from camelCase to snake_case
      • Wraps parameters in the JSON-RPC format
      • Returns a properly typed JsonRpcResponse<Result, Error>

Type Definitions

import type { JsonRpcResponse, RequestProvider, DeepReadonly } from '@budarin/json-rpc-api-provider';

// JsonRpcResponse<T, E = unknown>
interface JsonRpcResponse<T, E = unknown> {
    result?: T;
    error?: {
        code: number;
        message: string;
        data?: E;
    };
}

// Request object structure
interface Request {
    body: {
        id: string;
        method: string;
        params?: unknown;
    };
}

🔒 TypeScript Support

This library is written in TypeScript and provides full type safety:

  • Generic API Interfaces: Define your entire API surface with TypeScript interfaces
  • Type Inference: Response types are automatically inferred from your interface
  • Deep Readonly: Request objects are deeply immutable to prevent accidental mutations
  • Error Types: Support for custom error types via generics
  • No any Types: Strict typing throughout the library

Example with Full Type Safety

interface Product {
    id: string;
    name: string;
    price: number;
}

interface ValidationError {
    field: string;
    message: string;
}

interface ProductAPI {
    getProduct: (id: string) => Promise<JsonRpcResponse<Product, ValidationError>>;
}

const api = createApiProvider<ProductAPI>(request, uuidv7);

const response = await api.getProduct('123');
//    ^? JsonRpcResponse<Product, ValidationError>

if (response.error) {
    //  ^? { code: number; message: string; data?: ValidationError }
    console.error(response.error.data?.field);
    //                              ^? string | undefined
}

if (response.result) {
    //  ^? Product | undefined
    console.log(response.result.name);
    //                          ^? string
}

🤝 Integration with @budarin/json-rpc-request

This library is designed to work seamlessly with @budarin/json-rpc-request. The core types and utilities are re-exported from this package for convenience:

  • JsonRpcResponse - Type definitions for JSON-RPC responses
  • Request - Request interface for HTTP communication
  • DeepReadonly - Utility type for immutable objects

All necessary types are available directly from @budarin/json-rpc-api-provider, providing a complete, type-safe solution for JSON-RPC APIs.

📄 License

MIT © Vadim Budarin

🔗 Related Packages