Skip to content
Back to skills

Orpc Building Custom Plugins

ASecurity

Create powerful custom plugins to extend oRPC handlers and links with interceptors.

  • 8 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 12, 2026
devopsgitapi

Works with

  • cli
  • api

Security analysis

A100/100

Scanned September 12, 2026

npx -y skills add ali-master/skills --skill orpc-building-custom-plugins --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Orpc Building Custom Plugins?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Orpc Building Custom Plugins
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/ali-master-orpc-building-custom-plugins/badge)](https://www.skillsdirectory.com/skills/ali-master-orpc-building-custom-plugins)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: oRPC Building Custom Plugins
description: Create powerful custom plugins to extend oRPC handlers and links with interceptors.
license: MIT
metadata:
  author: Ali Torki
  homepage: https://github.com/ali-master
  version: "1.0.0"
---

# Building Custom Plugins

This guide explains how to create custom oRPC plugins for handlers and links.

## What is a Plugin?

In oRPC, a plugin is a collection of `interceptors` that can work together or independently.

```ts
export class ResponseHeadersPlugin<T extends ResponseHeadersPluginContext> implements StandardHandlerPlugin<T> {
  init(options: StandardHandlerOptions<T>): void {
    options.rootInterceptors ??= []

    options.rootInterceptors.push(async (interceptorOptions) => {
      const resHeaders = interceptorOptions.context.resHeaders ?? new Headers()

      const result = await interceptorOptions.next({
        ...interceptorOptions,
        context: { ...interceptorOptions.context, resHeaders },
      })

      if (!result.matched) return result

      const responseHeaders = clone(result.response.headers)

      for (const [key, value] of resHeaders) {
        // merge headers
        responseHeaders[key] = value
      }

      return { ...result, response: { ...result.response, headers: responseHeaders } }
    })
  }
}
```

### Handler Plugins

Extend server-side handlers (RPCHandler, OpenAPIHandler). Work with interceptors from the [Handler Lifecycle](/docs/rpc-handler#lifecycle).

### Link Plugins

Enhance client-side communication (RPCLink, OpenAPILink). Use interceptors from the [Link Lifecycle](/docs/client/rpc-link#lifecycle).

## Communication Between Interceptors

Use a unique symbol to inject context shared between interceptors. The [Strict Get Method Plugin](/docs/plugins/strict-get-method) demonstrates this — it uses `rootInterceptors` to collect HTTP methods and combines them with procedure info in `clientInterceptors`.

## Plugin Order

```ts
export class ExamplePlugin<T extends Context> implements StandardHandlerPlugin<T> {
  order = 10

  init(options: StandardHandlerOptions<T>): void {
    options.rootInterceptors ??= []
    options.clientInterceptors ??= []

    options.rootInterceptors.push(async ({ next }) => next())
    options.clientInterceptors.push(async ({ next }) => next())
  }
}
```

`order` controls plugin loading order, not interceptor execution order. Higher order with `.unshift` to run earlier, or `.push` to run later.

> Avoid setting `order` unless necessary. Keep it below `1_000_000` to avoid conflicts with built-in plugins.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.