---
title: xxrpc_handler
description: Generate typed framework-neutral ECMAScript RPC handler classes.
---

# `xxrpc_handler`

`xxrpc_handler` generates Protobuf-ES message sources and abstract TypeScript handler classes for unary, client-streaming, server-streaming, and bidirectional RPC methods. Generation runs during `xx run`; pass the returned dependency to `deps` when another task needs the generated files.

## Arguments

| Argument | Required | Description |
| --- | --- | --- |
| `srcs` | Yes | Non-empty list of project-relative `.proto` files. |
| `out_es` | Yes | Project-relative ECMAScript output directory. |
| `deps` | No | Dependencies that provide `protoc` and `protoc-gen-es`. Defaults to `[]`. |

Load `protoc` from an exact [`@protobuf`](../protobuf/protoc.md) package. Install `@bufbuild/protoc-gen-es` version 2 in the project and make `node_modules/.bin` available through `deps`. xxRPC checks for `protoc-gen-es` before invoking `protoc` and does not install or select a plugin version.

Each generated `<source>_xxrpc.ts` file exports one abstract `<Service>Handler` class per Protobuf service. Handler implementations use only standard TypeScript types and generated Protobuf messages:

| Protobuf method | Handler input | Handler result |
| --- | --- | --- |
| Unary | `Input` | `Promise<Output>` |
| Server streaming | `Input` | `AsyncIterable<Output>` |
| Client streaming | `AsyncIterable<Input>` | `Promise<Output>` |
| Bidirectional streaming | `AsyncIterable<Input>` | `AsyncIterable<Output>` |

Every method also receives an `XXRPCContext` containing an `AbortSignal`. The signal is aborted when the request or WebSocket disconnects or the client cancels. Implementations do not import Node.js, Cloudflare, Vercel, or another server framework.

The generated `handle(request: Request)` method handles unary calls:

- accepts HTTP `POST` requests with a raw Protobuf body;
- routes with `X-XXRPC-Service` and `X-XXRPC-Method` headers and requires `X-XXRPC-Streaming: 0`;
- decodes and encodes messages with `@bufbuild/protobuf`;
- passes `request.signal` through `XXRPCContext`;
- returns `400` for an invalid Protobuf body, `404` for an unknown service or method, `405` for another HTTP method, and `413` for a body larger than 4 MiB;
- catches every implementation throw and returns HTTP `500` without exposing the thrown value.

The generated `prepareStreaming(request)` method validates a WebSocket request before an adapter upgrades it. The request must use `xxrpc.streaming.v1`, include exactly one `xxrpc-service` and `xxrpc-method` URL parameter, and name a streaming method. Requesting a unary method through WebSocket or a streaming method through HTTP returns HTTP `400`.

`XXRPCPreparedStream` accepts a small `XXRPCSocket` interface. Platform adapters only translate their WebSocket implementation to this interface; Protobuf dispatch, flow control, cancellation, and errors remain in the generated generic core.

### Cloudflare Workers

Handler generation also writes `<source>_xxrpc_cloudflare.ts`. It exports `createCloudflareXXRPCHandler`, which handles both standard Fetch requests and `WebSocketPair` upgrades:

```ts
import { Greeter } from "./greeter.js";
import { createCloudflareXXRPCHandler } from "./generated/contracts/greeter_xxrpc_cloudflare.js";

const handle = createCloudflareXXRPCHandler(new Greeter());

export default {
  fetch(request: Request): Promise<Response> {
    return handle(request);
  },
};
```

The adapter is generated separately so the generic handler module contains no Cloudflare APIs or type dependencies. Authentication and origin checks should run before calling the generated adapter.

## Example

```starlark
load("@nodejs@22.14.0", "npm_install")
load("@os@1", "env_prepend")
load("@protobuf@35.1", "protoc")
load("@xxrpc@1", "xxrpc_handler")

install = npm_install()

rpc_server = xxrpc_handler(
    srcs=["contracts/greeter.proto"],
    out_es="backend/generated",
    deps=[
        protoc,
        install,
        env_prepend("PATH", "node_modules/.bin"),
    ],
)
```

Sources retain their path below the project root. `contracts/greeter.proto` produces these files:

- `backend/generated/contracts/greeter_pb.js`
- `backend/generated/contracts/greeter_pb.d.ts`
- `backend/generated/contracts/greeter_xxrpc.ts`
- `backend/generated/contracts/greeter_xxrpc_cloudflare.ts`

The output directory is owned by the xxRPC task. Obsolete generated files from preceding generations are removed before generation.

<!--
Sitemap

URL: https://withxx.dev/index.md
Title: xx
Description: Practical, reproducible builds without build-system ceremony

URL: https://withxx.dev/examples/commands.md
Title: Command Examples
Description: General command, environment, and entrypoint patterns.

URL: https://withxx.dev/examples/go.md
Title: Go Examples
Description: Common Go build patterns with managed SDKs.

URL: https://withxx.dev/examples/nodejs.md
Title: Node.js Examples
Description: Common Node.js task patterns with a managed distribution.

URL: https://withxx.dev/examples/zig.md
Title: Zig Examples
Description: Direct Zig commands and Go CGO builds with a managed Zig distribution.

URL: https://withxx.dev/load.md
Title: Loading Files
Description: Split xx configuration into local Starlark modules.

URL: https://withxx.dev/lsp.md
Title: Editor Support
Description: Configure an editor to use xx's built-in Starlark language server.

URL: https://withxx.dev/packages/cloudflare/cf_d1_create.md
Title: cf_d1_create
Description: Provision a Cloudflare D1 database with Wrangler.

URL: https://withxx.dev/packages/cloudflare/cf_kv_create.md
Title: cf_kv_create
Description: Provision a Cloudflare Workers KV namespace with Wrangler.

URL: https://withxx.dev/packages/cloudflare/cf_queue_create.md
Title: cf_queue_create
Description: Provision and configure a Cloudflare Queue with Wrangler.

URL: https://withxx.dev/packages/cloudflare/cf_r2_create.md
Title: cf_r2_create
Description: Provision and configure a Cloudflare R2 bucket with Wrangler.

URL: https://withxx.dev/packages/cloudflare/cf_worker_config.md
Title: cf_worker_config
Description: Define an in-memory Cloudflare Worker configuration.

URL: https://withxx.dev/packages/cloudflare/cf_wrangler_deploy.md
Title: cf_wrangler_deploy
Description: Deploy a Cloudflare Worker with a temporary Wrangler configuration.

URL: https://withxx.dev/packages/cloudflare/cf_wrangler_dev.md
Title: cf_wrangler_dev
Description: Run one or more Cloudflare Workers with Wrangler dev.

URL: https://withxx.dev/packages/cmake/cmake.md
Title: cmake
Description: Activate managed CMake for dependent tasks.

URL: https://withxx.dev/packages/cmake/cmake_build.md
Title: cmake_build
Description: Build a generated project with managed CMake.

URL: https://withxx.dev/packages/cmake/cmake_generate.md
Title: cmake_generate
Description: Generate a project build system with managed CMake.

URL: https://withxx.dev/packages/doppler/doppler_secrets.md
Title: doppler_secrets
Description: Load Doppler secrets into dependent task environments.

URL: https://withxx.dev/packages/git/git_clone.md
Title: git_clone
Description: Materialize a pinned Git source tree with host Git configuration and access.

URL: https://withxx.dev/packages/git/git_commit.md
Title: git_commit
Description: Stage and commit changes in a Git repository.

URL: https://withxx.dev/packages/git/git_init_repository.md
Title: git_init_repository
Description: Ensure an empty SHA-1 or SHA-256 Git repository exists.

URL: https://withxx.dev/packages/git/git_push.md
Title: git_push
Description: Push commits from a Git repository.

URL: https://withxx.dev/packages/git/git_semver_latest.md
Title: git_semver_latest
Description: Read the latest semantic version from local Git tags.

URL: https://withxx.dev/packages/git/git_semver_next.md
Title: git_semver_next
Description: Calculate the next semantic version from local Conventional Commits.

URL: https://withxx.dev/packages/git/git_sha.md
Title: git_sha
Description: Resolve a local Git revision to its commit ID.

URL: https://withxx.dev/packages/git/git_tag.md
Title: git_tag
Description: Create a lightweight or annotated Git tag.

URL: https://withxx.dev/packages/go/go.md
Title: go
Description: Activate a managed Go SDK for dependent tasks.

URL: https://withxx.dev/packages/go/go_binary.md
Title: go_binary
Description: Build a Go command with a managed SDK.

URL: https://withxx.dev/packages/go/go_install.md
Title: go_install
Description: Install a versioned Go command for dependent tasks.

URL: https://withxx.dev/packages/go/go_protobuf.md
Title: go_protobuf
Description: Install protoc-gen-go and provide it as a Protobuf generator.

URL: https://withxx.dev/packages/go/go_run.md
Title: go_run
Description: Run a local program or versioned Go command with a managed SDK.

URL: https://withxx.dev/packages/go/go_test.md
Title: go_test
Description: Test Go packages with a managed SDK.

URL: https://withxx.dev/packages/http/http_proxy.md
Title: http_proxy
Description: Route local HTTP and WebSocket traffic between development servers.

URL: https://withxx.dev/packages/io/io_append_text.md
Title: io_append_text
Description: Append text to a file asynchronously.

URL: https://withxx.dev/packages/io/io_copy.md
Title: io_copy
Description: Copy a file or directory asynchronously.

URL: https://withxx.dev/packages/io/io_glob.md
Title: io_glob
Description: Find project files and directories with recursive glob patterns.

URL: https://withxx.dev/packages/io/io_read_text.md
Title: io_read_text
Description: Read a text file during build evaluation.

URL: https://withxx.dev/packages/io/io_rm.md
Title: io_rm
Description: Remove a file asynchronously.

URL: https://withxx.dev/packages/io/io_rmdir.md
Title: io_rmdir
Description: Remove a directory tree asynchronously.

URL: https://withxx.dev/packages/io/io_stat.md
Title: io_stat
Description: Read file information during build evaluation.

URL: https://withxx.dev/packages/io/io_write_text.md
Title: io_write_text
Description: Write text to a file asynchronously.

URL: https://withxx.dev/packages/ninja/ninja.md
Title: ninja
Description: Activate managed Ninja for dependent tasks.

URL: https://withxx.dev/packages/nodejs/nodejs.md
Title: nodejs
Description: Activate managed Node.js for dependent tasks.

URL: https://withxx.dev/packages/nodejs/npm_install.md
Title: npm_install
Description: Install dependencies with the package.json-selected manager.

URL: https://withxx.dev/packages/nodejs/npm_run.md
Title: npm_run
Description: Run a project package script with the package.json-selected manager.

URL: https://withxx.dev/packages/nodejs/npx_run.md
Title: npx_run
Description: Run a versioned npm package command with managed npx.

URL: https://withxx.dev/packages/os/env_append.md
Title: env_append
Description: Append an item to a list-like environment variable.

URL: https://withxx.dev/packages/os/env_get.md
Title: env_get
Description: Read a value from a task environment while evaluating Starlark.

URL: https://withxx.dev/packages/os/env_prepend.md
Title: env_prepend
Description: Prepend an item to a list-like environment variable.

URL: https://withxx.dev/packages/os/env_set.md
Title: env_set
Description: Set an environment variable for dependent tasks.

URL: https://withxx.dev/packages/os/env_unset.md
Title: env_unset
Description: Remove an environment variable from dependent tasks.

URL: https://withxx.dev/packages/os/os_arch.md
Title: os_arch
Description: Identify the host processor architecture.

URL: https://withxx.dev/packages/os/os_kernel.md
Title: os_kernel
Description: Identify the host operating system kernel.

URL: https://withxx.dev/packages/os/os_msvc.md
Title: os_msvc
Description: Activate the host Microsoft Visual C++ tools.

URL: https://withxx.dev/packages/os/os_run.md
Title: os_run
Description: Run a command from a project directory.

URL: https://withxx.dev/packages/os/os_system_tools.md
Title: os_system_tools
Description: Activate standard host operating-system utilities.

URL: https://withxx.dev/packages/os/os_xcode.md
Title: os_xcode
Description: Activate the host Xcode tools.

URL: https://withxx.dev/packages/os/path_make_absolute.md
Title: path_make_absolute
Description: Resolve a relative path from the project root.

URL: https://withxx.dev/packages/protobuf/protobuf_generate.md
Title: protobuf_generate
Description: Generate source code with a managed Protobuf compiler.

URL: https://withxx.dev/packages/protobuf/protobuf_generator.md
Title: protobuf_generator
Description: Adapt an installed protoc plugin dependency for code generation.

URL: https://withxx.dev/packages/protobuf/protoc.md
Title: protoc
Description: Activate a managed Protobuf compiler for dependent tasks.

URL: https://withxx.dev/packages/secrets/xx_secrets.md
Title: xx_secrets
Description: Load xx project secrets into dependent task environments.

URL: https://withxx.dev/packages/stripe/stripe.md
Title: stripe
Description: Activate a managed Stripe CLI for dependent tasks.

URL: https://withxx.dev/packages/stripe/stripe_listen.md
Title: stripe_listen
Description: Forward Stripe webhook events to a local endpoint.

URL: https://withxx.dev/packages/text/text_template.md
Title: text_template
Description: Render Go text templates from Starlark data and functions.

URL: https://withxx.dev/packages/xxrpc/xxrpc_client.md
Title: xxrpc_client
Description: Generate typed HTTP and WebSocket RPC clients for ECMAScript or Go.

URL: https://withxx.dev/packages/xxrpc/xxrpc_handler.md
Title: xxrpc_handler
Description: Generate typed framework-neutral ECMAScript RPC handler classes.

URL: https://withxx.dev/packages/zig/zig.md
Title: zig
Description: Activate managed Zig for dependent tasks.

URL: https://withxx.dev/packages/zig/zig_cc.md
Title: zig_cc
Description: Configure managed Zig as a C and C++ compiler.

URL: https://withxx.dev/packages.md
Title: Built-in Packages
Description: Versioned toolchains, commands, and task environment helpers provided by xx.

URL: https://withxx.dev/secrets.md
Title: Secret manager
Description: Store project secrets locally and provide them to xx tasks.

URL: https://withxx.dev/xxrpc.md
Title: xxRPC
Description: Design portable xxRPC contracts that keep application semantics in Protobuf.
-->
