Workers RPC Now Bridges Python and JavaScript: No Schemas, No Serialization Code

TL;DR
Workers RPC now bridges Python and JavaScript, passing live objects, functions and streams between Workers with no schemas and no serialization code.
Last updated: October 18, 2026
Updated October 18, 2026: The code samples match Cloudflare's announcement, Workers RPC now works across Python and JavaScript, which the post now links. Added the Service binding the Python sample depends on, as shown in that post.
Two years ago Cloudflare built an RPC system into Workers that made calling another Worker's methods feel like a local function call: live objects, functions, and streams crossing process boundaries with no schemas and no dependencies. It was called "JavaScript-native RPC" for a reason, it only spoke JavaScript. On August 3, as part of Agents Week, Cloudflare removed that constraint. Workers RPC now works across Python and JavaScript, in both directions, with no protocol definitions and no serialization code.
What shipped#
The change is a capability expansion of the existing RPC system, built on Cap'n Proto, that Workers have had since 2024. You configure a Service binding, and a TypeScript Worker can call a method on a Python Worker as if it were a local module:
// TypeScript worker
import { WorkerEntrypoint } from "cloudflare:workers";
export class RpcService extends WorkerEntrypoint {
async add(a: number, b: number): Promise<number> {
return a + b;
}
}
# Python worker
from workers import Response, WorkerEntrypoint
class Default(WorkerEntrypoint):
async def fetch(self, request):
rpc = self.env.RPC
result = await rpc.add(42, 144)
return Response.json({"result": result})
The only wiring is the Service binding in the Python Worker's wrangler.jsonc, here pointing at the TypeScript Worker's RpcService entrypoint (from the announcement; see the Service bindings docs):
"services": [
{
"binding": "RPC",
"service": "ts-rpc-server",
"entrypoint": "RpcService"
}
]
No protobuf files, no code generation, no JSON envelopes.
What can cross the boundary is more interesting than plain numbers. Structured-cloneable values convert to the appropriate native type on the other side (a JS Date becomes a Python datetime). You can pass functions into a Python Worker and call them back, which makes cross-language callbacks and streams work without any glue. Python keyword arguments map onto JavaScript's object-style parameters, so a JS method like get(key, { type: "text" }) can be called from Python as get("myKey", type="text").
The type translation is the mechanical heart of the feature, and it has two layers. Pyodide, the CPython-to-WebAssembly interpreter that has powered Python Workers since launch, already ships a foreign function interface that maps int and float to Number, bool to Boolean, dict to Object, and list to Array. Where direct translation is impossible, Pyodide creates a proxy object that forwards attribute access and method calls across the boundary, which is how passing a Python function as a JavaScript callback works.
The second layer is a thin conversion package, workers-runtime-sdk, which handles Cloudflare's own Web API objects: Request, Response, Blob, and File. Without it, Pyodide treats those as opaque JavaScript proxies, leaking implementation details into Python code. With it, they become idiomatic Python objects. The package is included by default when you deploy with uv run pywrangler deploy, so importing from the workers namespace already uses it.
Why it matters to developers#
The clearest framing is in the announcement itself: one coding agent can write a Python Worker and another can write a JavaScript Worker, and the runtime handles the rest. That matters more than it sounds, because the barrier this removes is not just boilerplate, it is the interface contract. Teams routinely split services by language to reuse a library: a Python ecosystem like Pygments for syntax highlighting, or a JS ecosystem like a frontend framework. The standard answer is to build an HTTP API or a protobuf service around the one library, and then maintain that contract forever. RPC across the boundary removes the contract from the critical path: the method signature is the interface, and the runtime translates.
Three things stand out:
-
Same-thread execution changes the cost model. RPC between Workers usually does not cross a network. The other Worker typically runs in the same thread as the caller, and Cloudflare claims near-zero overhead compared with in-process code. That is a different category from HTTP calls between services, and it is why the "no schemas" pattern stays fast enough to be the default rather than an optimization.
-
The type-bridging is the real product. Languages disagree about the most basic shapes: JavaScript passes object arguments, Python passes keyword arguments. Cloudflare picked the mapping (keyword arguments to object fields, dates to datetimes, functions to callable proxies) so neither side writes adapter code. That is the difference between "RPC that exists" and "RPC that feels native," and it is the hard part to get right.
-
It is the polyglot layer for agent-built systems. The Agents Week context is deliberate. Agent-generated services increasingly arrive in different languages because the generating model favors different toolchains per task. A platform that lets those services call each other without a human-written contract removes a whole class of integration work from agent workflows.
The honest constraints#
This is a general-availability feature, not a beta, but it inherits the platform's real constraints. Python Workers run CPython compiled to WebAssembly through Pyodide, so performance-sensitive Python code is still bounded by the WASM interpreter. Pyodide's FFI proxy objects work, but deep object graphs crossing the boundary repeatedly will cost more than a native call. And while the RPC system is open source in workerd, you get this cross-language path in the Workers runtime, not in a standalone library you can drop into any FastAPI or Express deployment.
How it fits with adjacent tools#
The same week, Cloudflare also shipped inbound TCP and gRPC for Workers, which pairs naturally with this: RPC covers internal service-to-service calls, gRPC covers client-facing APIs, and both now work with Python. The agent angle connects to the multi-agent orchestration space, where teams are building heterogeneous agent fleets that need cheap, typed communication between components. And the "open weights everywhere" story from today, with Qwen 3.8 Max promising the first open-weights Max-class release, is another push toward mixed ecosystems where polyglot service boundaries are the norm rather than the exception.
FAQ#
Can a TypeScript Worker call a Python Worker on Cloudflare?#
Yes. Workers RPC now works across Python and JavaScript in both directions. You configure a Service binding in wrangler.jsonc, and a Worker can call methods on a Worker written in the other language as if it were a local module, with no protobuf files, code generation, or JSON envelopes.
How are types converted between Python and JavaScript in Workers RPC?#
Pyodide's foreign function interface maps int and float to Number, bool to Boolean, dict to Object, and list to Array, and creates proxy objects where direct translation is impossible. The workers-runtime-sdk package converts Cloudflare's Request, Response, Blob, and File objects into idiomatic Python objects, and a JS Date becomes a Python datetime.
How do Python keyword arguments map to JavaScript methods?#
Python keyword arguments map onto JavaScript's object-style parameters, so a JS method like get(key, { type: "text" }) can be called from Python as get("myKey", type="text").
Is cross-language Workers RPC slow?#
Usually not. RPC between Workers typically does not cross a network because the other Worker runs in the same thread as the caller, and Cloudflare claims near-zero overhead compared with in-process code. Python code is still bounded by the Pyodide WebAssembly interpreter, and deep object graphs crossing the boundary repeatedly cost more than a native call.
Is Python and JavaScript Workers RPC in beta?#
No. It is a general-availability feature, available now. The cross-language path runs in the Workers runtime rather than as a standalone library you can drop into another deployment.
Continue Reading#
- Cloudflare's Agent Runtime Preview: The Computer Your Agent Gets
- Workers Can Now Accept Inbound TCP and Serve gRPC
- Building Multi-Agent Workflows with Claude Code
- Vercel's Durable Execution Programming Model
- Qwen 3.8 Max: First Open-Weights Max-Class Flagship
- Headroom: Compress Agent Tool Output Before It Reaches the LLM
Sources#
- Workers RPC now works across Python and JavaScript - Cloudflare Blog
- Welcome to Agents Week - Cloudflare Blog
- Workers RPC runtime APIs - Cloudflare Docs
- Python Workers documentation - Cloudflare Docs
- workerd - GitHub
- workers-runtime-sdk - GitHub
- Cross-language RPC example: 13-js-api-pygments - GitHub
Get the next deep dive like this in your inbox
One email a week on News and the rest of the AI dev stack. Free.
Read next on AI coding tools
@cloudflare/computer: an Agent Runtime That Treats a Container as a Tool, Not a Home
@cloudflare/computer is an open-source agent runtime: an SQLite-backed shared workspace plus a per-task choice between fast isolates and full Linux containers.
7 min readWorkers Can Now Accept Inbound TCP and Serve gRPC: Cloudflare Closes the HTTP-Only Gap
Cloudflare Workers can now accept inbound TCP and serve gRPC: a connect() handler via Spectrum, full-duplex gRPC from Containers, and gRPC-web translation.
6 min readBuilding Multi-Agent Workflows in Claude Code: A Practical Tutorial
Multi-agent workflows in Claude Code: use the Task tool, custom sub-agents and worktrees to run parallel development, with real prompts and agent configs.
11 min readNew here? Start with
Technical content at the intersection of AI and development. Building with AI agents, Claude Code, and modern dev tools - then showing you exactly how it works.







