Socket
Book a DemoInstallSign in
Socket

typesafe-rpc

Package Overview
Dependencies
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

typesafe-rpc

A typesafe RPC library for Node.js, TypeScript and React.

latest
Source
npmnpm
Version
0.0.17
Version published
Weekly downloads
217
4240%
Maintainers
1
Weekly downloads
 
Created
Source

TypeSafe RPC

NPM Version License: MIT

A modern, type-safe RPC (Remote Procedure Call) library for Node.js, TypeScript, and React applications. Built with full TypeScript support, providing end-to-end type safety between client and server.

🚀 Features

  • Full TypeScript Support: Complete type safety from server to client
  • Modern Architecture: Built for modern web applications with ES modules
  • Middleware Support: Extensible middleware system for authentication, logging, and more
  • Performance Monitoring: Built-in hooks for performance tracking
  • Error Handling: Comprehensive error handling with customizable error responses
  • Abort Signal Support: Cancel requests with AbortController
  • Zero Dependencies: Minimal runtime dependencies for optimal bundle size

📦 Installation

npm install typesafe-rpc
# or
yarn add typesafe-rpc
# or
pnpm add typesafe-rpc

🎯 Quick Start

1. Define Your API Schema

// api-schema.ts
import type { BaseContext, Handler } from 'typesafe-rpc';

type UserContext = BaseContext & {
  user?: { id: string; name: string };
};

type UserParams = { id: string };
type UserResult = { id: string; name: string; email: string };

const getUserHandler: Handler<UserParams, UserContext, UserResult, {}> = async ({
  params,
  context,
}) => {
  // Your business logic here
  return {
    id: params.id,
    name: 'John Doe',
    email: 'john@example.com',
  };
};

export const apiSchema = {
  users: {
    getById: getUserHandler,
  },
} as const;

2. Set Up the Server

// server.ts
import { createRpcHandler } from 'typesafe-rpc/server';

import { apiSchema } from './api-schema';

export async function handleRequest(request: Request): Promise<Response> {
  const context = { request };

  return createRpcHandler({
    context,
    operations: apiSchema,
    errorHandler: (error) => {
      console.error('RPC Error:', error);
      return new Response(JSON.stringify({ error: 'Internal Server Error' }), {
        status: 500,
        headers: { 'Content-Type': 'application/json' },
      });
    },
    hooks: {
      preCall: (context) => console.log('RPC call started'),
      postCall: (context, performance) => console.log(`RPC call completed in ${performance}ms`),
      error: (context, performance, error) =>
        console.error(`RPC call failed after ${performance}ms:`, error),
    },
  });
}

3. Create the Client

// client.ts
import { createRpcClient } from 'typesafe-rpc/client';

import type { apiSchema } from './api-schema';

const client = createRpcClient<typeof apiSchema>('/api/rpc');

// Usage with full type safety
const user = await client.users.getById({ id: '123' });
console.log(user.name); // TypeScript knows this exists!

4. Use in React

// React component
import { useState, useEffect } from 'react';
import { client } from './client';

function UserProfile({ userId }: { userId: string }) {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const controller = new AbortController();

    client.users.getById({ id: userId }, controller.signal)
      .then(setUser)
      .catch(console.error)
      .finally(() => setLoading(false));

    return () => controller.abort();
  }, [userId]);

  if (loading) return <div>Loading...</div>;
  if (!user) return <div>User not found</div>;

  return (
    <div>
      <h1>{user.name}</h1>
      <p>{user.email}</p>
    </div>
  );
}

🔧 API Reference

Core Types

BaseContext

type BaseContext = {
  request: Request;
};

Handler<Params, Context, Result, ExtraParams>

type Handler<Params, Context extends BaseContext, Result, ExtraParams> = (
  args: Args<Params, Context, ExtraParams>,
) => Promise<Result>;

RpcSchema

type RpcSchema = {
  [entity: string]: {
    [operation: string]: Handler<any, any, any, any>;
  };
};

Server API

createRpcHandler<T, Context>

Creates an RPC handler for processing requests.

function createRpcHandler<T extends RpcSchema, Context extends BaseContext>({
  context,
  operations,
  errorHandler?,
  hooks?,
}: {
  context: Context;
  operations: T;
  errorHandler?: (error: any) => Response;
  hooks?: {
    preCall?: (context: Context) => void;
    postCall?: (context: Context, performance: number) => void;
    error?: (context: Context, performance: number, error: any) => void;
  };
}): Promise<Response>

Client API

createRpcClient<T>(endpoint)

Creates a type-safe RPC client.

function createRpcClient<T extends RpcSchema>(endpoint: string): RpcClient<T>;

The returned client provides a proxy that matches your schema structure with full type safety.

Middleware System

import type { Middleware } from 'typesafe-rpc';

// Authentication middleware
const authMiddleware: Middleware<any, BaseContext, {}, { user: { id: string } }> = async ({
  context,
}) => {
  const token = context.request.headers.get('Authorization');
  if (!token) throw new Response('Unauthorized', { status: 401 });

  // Verify token and return user info
  return { user: { id: 'user-123' } };
};

// Usage in handler
const protectedHandler: Handler<
  UserParams,
  BaseContext,
  UserResult,
  { user: { id: string } }
> = async ({ params, context, extraParams }) => {
  // extraParams.user is now available with full type safety
  return {
    /* ... */
  };
};

🛠️ Development

Prerequisites

  • Node.js 18+
  • Yarn 4.9.2+

Setup

git clone https://github.com/bacali95/typesafe-rpc.git
cd typesafe-rpc
yarn install

Available Scripts

# Build the library
yarn build

# Run tests
yarn test

# Lint code
yarn lint

# Format code
yarn prettier:fix

# Check code formatting
yarn prettier:check

🤝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

  • Fork the repository
  • Create a feature branch (git checkout -b feature/amazing-feature)
  • Commit your changes (git commit -m 'Add amazing feature')
  • Push to the branch (git push origin feature/amazing-feature)
  • Open a Pull Request

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

🙏 Acknowledgments

  • Built with Nx for monorepo management
  • TypeScript-first design for maximum developer experience
  • Modern web standards with ES modules and Fetch API

📞 Support

Made with ❤️ by Nasreddine Bac Ali

Keywords

typescript

FAQs

Package last updated on 31 Dec 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts