# delight-rpc

> The easiest-to-use RPC library designed for TypeScript and JavaScript.

Latest version **7.0.1** (published 2026-10-18) · MIT license · 0 weekly downloads

## Install

```sh
npm install delight-rpc
pnpm add delight-rpc
yarn add delight-rpc
bun add delight-rpc
```

## Health

**Score 70/100 (B)** — status: active.

Positive: has types; esm support; no vulnerabilities; recently updated; high maintenance score; high quality score.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 7.0.1 |
| Published | 2026-10-18 |
| First published | 2020-12-20 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Node | >=22 |
| Dependencies | 10 |
| Unpacked size | 68.3 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | BlackGlory |
| Maintainers | black_glory |

## Links

- npm: https://www.npmjs.com/package/delight-rpc
- Repository: https://github.com/delight-rpc/delight-rpc
- Homepage: https://github.com/delight-rpc/delight-rpc#readme
- Issues: https://github.com/delight-rpc/delight-rpc/issues
- npm.io page: https://npm.io/package/delight-rpc

## Dependencies (10)

- [nanoid](https://npm.io/package/nanoid.md) ^6.0.2
- [semver](https://npm.io/package/semver.md) ^7.8.5
- [hotypes](https://npm.io/package/hotypes.md) ^0.6.6
- [extra-abort](https://npm.io/package/extra-abort.md) ^0.5.1
- [return-style](https://npm.io/package/return-style.md) ^4.0.0
- [extra-promise](https://npm.io/package/extra-promise.md) ^7.1.1
- [@blackglory/errors](https://npm.io/package/@blackglory/errors.md) ^3.1.0
- [@blackglory/prelude](https://npm.io/package/@blackglory/prelude.md) ^0.5.0
- [object-path-operator](https://npm.io/package/object-path-operator.md) ^5.2.2
- [@delight-rpc/protocol](https://npm.io/package/@delight-rpc/protocol.md) ^4.1.1

## Recent versions

- 7.0.1 (latest) — 2026-10-18
- 7.0.0 — 2026-02-25
- 6.1.3 — 2026-02-25
- 6.1.2 — 2023-04-04
- 6.1.1 — 2023-04-03
- 6.1.0 — 2023-04-03
- 6.0.1 — 2023-03-19
- 6.0.0 — 2023-03-19
- 5.1.0 — 2023-02-23
- 5.0.4 — 2023-02-11
- 5.0.3 — 2023-01-28
- 5.0.2 — 2023-01-28
- 5.0.1 — 2023-01-21
- 5.0.0 — 2022-12-15
- 4.3.2 — 2022-10-31
- … 48 more at https://npm.io/package/delight-rpc/versions

## README

# delight-rpc
The easiest-to-use RPC library designed for TypeScript and JavaScript.

## Install
```sh
npm install --save delight-rpc
# or
yarn add delight-rpc
```

## Usage
### Client
```ts
import { createClient } from 'delight-rpc'

interface IAPI {
  foo(bar: string): string
}

const client = createClient<IAPI>(send)
const result = await client.foo('bar')
```

### BatchClient
```ts
import { createBatchProxy, BatchClient } from 'delight-rpc'

interface IAPI {
  getNumber(): number
  getString(): string
}

const client = new BatchClient(send)
const proxy = createBatchProxy<IAPI>()
const results = await client.parallel(
  proxy.getNumber()
, proxy.getString()
)

// `Result` comes from the `return-style` module, it has Rust-like APIs
results[0] // Result<number, Error>
results[1] // Result<string, Error>
```

### Server
```ts
import { createResponse, IRequest, IBatchRequest } from 'delight-rpc'

const api: IAPI = {
  foo(bar: string) {
    return bar
  }
}

async function handle(
  request: IRequest<unknown> | IBatchRequest<unknown>
): Promise<IResponse<unknown> | IBatchResponse<unknown>> {
  return await createResponse(api, request)
}
```

## API
```ts
type ImplementationOf<Obj> = {
  [Key in FunctionKeys<Obj> | KeysByType<Obj, object>]:
    Obj[Key] extends (...args: infer Args) => infer Result
      ? (...args: [...args: Args, signal?: AbortSignal]) => Awaitable<Awaited<Result>>
      : ImplementationOf<Obj[Key]>
}

type ParameterValidators<Obj> = Partial<{
  [Key in FunctionKeys<Obj> | KeysByType<Obj, object>]:
    Obj[Key] extends (...args: infer Args) => unknown
      ? (...args: Args) => void
      : ParameterValidators<Obj[Key]>
}>
```

### createClient
```ts
type ClientProxy<Obj> = {
  [Key in FunctionKeys<Obj> | KeysByType<Obj, object>]:
    Obj[Key] extends (...args: infer Args) => infer Result
      ? (...args: [...args: Args, signal?: AbortSignal]) => Promise<Awaited<Result>>
      : ClientProxy<Obj[Key]>
}

function createClient<API extends object, DataType = unknown>(
  send: (
    request: IRequest<DataType>
  , signal?: AbortSignal
  ) => Awaitable<IResponse<DataType>>
, options?: {
    parameterValidators?: ParameterValidators<API>
    expectedVersion?: string
    channel?: string
  }
): ClientProxy<API>
```

For easy distinction, when the method is not available,
`MethodNotAvailable` will be thrown instead of the general `Error`.

### BatchClient
```ts
type MapRequestsToResults<RequestTuple extends IRequestForBatchRequest<unknown, unknown>[]> = {
  [Index in keyof RequestTuple]:
    RequestTuple[Index] extends IRequestForBatchRequest<infer T, unknown>
    ? Result<T, Error>
    : never
}

class BatchClient<DataType = unknown> {
  constructor(
    send: (batchRequest: IBatchRequest<DataType>) => Awaitable<
    | IError
    | IBatchResponse<DataType>
    >
  , options?: {
      expectedVersion?: string
      channel?: string
    }
  )

  async parallel<T extends IRequestForBatchRequest<unknown, DataType>[]>(
    ...requests: T
  ): Promise<MapRequestsToResults<T>>

  async series<T extends IRequestForBatchRequest<unknown, DataType>[]>(
    ...requests: T
  ): Promise<MapRequestsToResults<T>>
}
```

### createBatchProxy
```ts
type BatchClientProxy<Obj, DataType> = {
  [Key in FunctionKeys<Obj> | KeysByType<Obj, object>]:
    Obj[Key] extends (...args: infer Args) => infer Result
      ? (...args: Args) => IRequestForBatchRequest<Awaited<Result>, DataType>
      : BatchClientProxy<Obj[Key], DataType>
}

function createBatchProxy<API extends object, DataType = unknown>(
  options?: {
    parameterValidators?: ParameterValidators<API>
  }
): BatchClientProxy<API, DataType>
```

### createResponse
```ts
const AnyChannel

function createResponse<API, DataType>(
  api: ImplementationOf<API>
, request: IRequest<DataType> | IBatchRequest<DataType>
, { parameterValidators = {}, version, channel, signal, ownPropsOnly = false }: {
    parameterValidators?: ParameterValidators<API>
    version?: `${number}.${number}.${number}`
    channel?: string | RegExp | typeof AnyChannel
    ownPropsOnly?: boolean
    signal?: AbortSignal
  } = {}
): Promise<null | IResponse<DataType> | IBatchResponse<DataType>>
```

`createResponse` returns `null` if the channel does not match.

### MethodNotAvailable
```ts
class MethodNotAvailable extends CustomError {}
```

### VersionMismatch
```ts
class VersionMismatch extends CustomError {}
```

### InternalError
```ts
class InternalError extends CustomError {}
```

### isRequst
```ts
function isRequest<DataType>(val: unknown): val is IRequest<DataType>
```

### isResult
```ts
function isResult<DataType>(val: unknown): val is IResult<DataType>
```

### isError
```ts
function isError(val: unknown): val is IError
```

### isBatchRequest
```ts
function isBatchRequest<T>(val: unknown): val is IBatchRequest<T>
```

### isBatchResponse
```ts
function isBatchResponse<T>(val: unknown): val is IBatchResponse<T> 
```

### matchChannel
```ts
function matchChannel<DataType>(
  message: IDelightRPC
, channel:
  | undefined
  | string
  | RegExp
  | typeof AnyChannel
): boolean
```

### createAbort
```ts
function createAbort(id: string, channel: string | undefined): IAbort
```

### isAbort
```ts
function isAbort(val: unknown): val is IAbort
```

---
_Source: https://npm.io/package/delight-rpc · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
