# Python and JavaScript Workers can now call each other directly, no schema required!

Hi, it's me! I've got an exciting one from Cloudflare today: Python Workers and JavaScript Workers can now talk to each other directly, almost as if they were written in the same language!

## What was announced?

Cloudflare Blog just announced that Workers RPC now works across Python and JavaScript. Until now, remote procedure calls (RPC) between Workers only worked within the same language. Now a Python Worker can call a method on a JavaScript Worker directly, and vice versa, without you writing any API definitions, schemas, or serialization code. The core idea is that the two Workers exchange references to live objects and simply call methods on them.

## The story so far

Workers RPC itself has been around for two years, and last year Cloudflare added Cap'n Web, which extended the same idea to browser-to-server communication. But both were built around Workers written in the same language. If you wanted a Python Worker to talk to a JavaScript Worker, your real options were calling over HTTP with `fetch`, or hand-rolling a language-agnostic serialization format like protobuf. That extra plumbing added friction every time cross-language communication was needed.

## What changes

With this update, a Python Worker can grab a service-bound JavaScript Worker through `self.env` and `await` its methods as if they were local functions. The reverse also works: a JavaScript Worker can call into a Python Worker's methods, including ones backed by Python libraries. The post's own example has a JavaScript Worker calling a Python Worker's `highlight_code()` method to get syntax highlighting powered by Pygments.

This also matters in a world with more coding agents involved: as the original post puts it, one coding agent can write a Python Worker and another can write a JavaScript Worker, and at runtime those Workers can exchange references to live objects and call each other's methods without anyone defining APIs, schemas, or serialization code. Teams — or agents — working in different languages no longer need to agree on an API contract up front to collaborate.

## Dive Deep

Under the hood, this builds on Cap'n Proto RPC and Cap'n Web, plus Pyodide's FFI (Foreign Function Interface) — Pyodide being the CPython interpreter compiled to WebAssembly that powers Python Workers.

Pyodide's FFI automatically converts common types between the two languages:

- Python `int` / `float` maps to JavaScript `Number`
- Python `bool` maps to JavaScript `Boolean`
- Python `dict` maps to JavaScript `Object`
- Python `list` maps to JavaScript `Array`

Web-platform objects like `Request`, `Response`, `Blob`, and `File` aren't covered by the plain FFI, so Cloudflare ships a `workers-runtime-sdk` Python package that proxies them across the boundary. For any other unsupported type, Pyodide automatically creates a proxy object that forwards attribute access and method calls across languages.

Exceptions propagate too — they're thrown right at the call site, on whichever side made the call. And according to Cloudflare, the overhead is near-zero, comparable to calling a function within the same Worker. The whole thing is implemented as part of `workerd`, Cloudflare's open-source Workers runtime, so you can go read the actual source if you're curious.

Here's what the code looks like. First, a TypeScript Worker exposing a method via `WorkerEntrypoint`:

```typescript
export class RpcService extends WorkerEntrypoint {
    async add(a: number, b: number): Promise<number> {
        return a + b;
    }
}
```

Wire it up with a service binding:

```json
"services": [{"binding": "RPC", "service": "ts-rpc-server", "entrypoint": "RpcService"}]
```

And call it from a Python Worker:

```python
rpc = self.env.RPC
result = await rpc.add(42, 144)
```

You can try it locally by running `wrangler dev` for the JavaScript side and `pywrangler dev` for the Python side.

## Wrap-up

- Workers RPC now works across Python and JavaScript
- No need to write APIs, schemas, or serialization code — Workers exchange references to live objects and call methods directly
- Pyodide's FFI handles common type conversions automatically, with proxies for anything else
- Exceptions propagate across the boundary, and the performance overhead is near-zero
- The implementation is fully open source as part of workerd

If you want to reuse Python libraries from JavaScript (or the other way around), or you've got teams — or coding agents — working in different languages, this one is worth a look.
