pyRPC

Blog

Design notes, deep dives, and updates from the pyrpc team.

·14 minTutorial

From tRPC to pyRPC: what stays, what goes, what gets easier

Side-by-side comparison for tRPC users: same hooks, Python server, no Zod, no links chain.

·12 minDeep Dive

Why we chose TanStack Query — and what it gives you for free

Caching, stale-while-revalidate, deduplication, and mutation invalidation without reinventing the wheel.

·8 minDeep Dive

Testing procedure kinds: what we covered

Tests across four layers: Python decorators, introspection schema, codegen output, and adapter proxy.

·8 minDeep Dive

Backward compatibility: how @rpc stayed working through v0.9.0

Why bare @rpc, no-kinds adapters, and existing installs all work without changes.

·12 minDeep Dive

The CI/CD publish pipeline: tag-triggered, chained, OIDC

How publish.yml chains 6 jobs: PyPI via OIDC, npm types/client/react/adapters, and GitHub Release.

·10 minDeep Dive

How we publish: from git tag to npm and PyPI

The full release flow: release.mjs, tag push, CI chain, OIDC for PyPI, and manual fallback.

·8 minTutorial

The Svelte adapter: framework-native, zero ceremony

How createSvelteClient integrates with TanStack Svelte Query stores and Svelte-native patterns.

·8 minTutorial

The Vue adapter: same contract, Vue-native patterns

How createPyrpcVue uses plugins instead of providers, composables instead of hooks.

·12 minTutorial

Building the Next.js example app: file by file

Walkthrough of examples/nextjs: server.py, lib/pyrpc.ts, layout, RSC prefetch, and client hooks.

·6 minDeep Dive

The tiny change in @pyrpc/types that powers everything

Why ProcedureKinds and procedureKinds are in @pyrpc/types, and how the const satisfies pattern works.

·10 minDeep Dive

The npx daemon: 715x faster type generation

How a persistent Node.js process drops jsonschema-ts from 3.3s to 4.6ms.

·10 minDeep Dive

Inside the codegen template: what client.ts.j2 generates

What the Jinja2 template produces: Types interface, ProcedureKinds, procedureKinds, and model interfaces.

·8 minDeep Dive

Router.merge: how pyRPC handles namespaces

Split procedures into separate modules and combine them with Router.merge() for larger projects.

·12 minDeep Dive

How procedure kinds flow from Python to TypeScript

Trace @rpc.query/@rpc.mutation from Python decorator through introspection, codegen, and into typed hooks.

·10 minDeep Dive

Publishing guide: npm @pyrpc/* and PyPI

release.mjs, build order, GitHub Actions tag publish, and manual npm/twine steps for new adapter packages.

·8 minRelease

v0.9.0 — Framework adapters, procedure kinds, one api object

Release notes for @pyrpc/react, next, vue, svelte, server kinds, and the unified api DX.

·7 minTutorial

Migrating from createClient to TanStack hooks

Keep Promise calls via api.client / createCaller while adopting useQuery — and annotate mutations on the server.

·9 minTutorial

Vue and Svelte adapters: same contract, stack-native setup

createPyrpcVue with api.plugin, createSvelteClient with createQuery/createMutation, and TanStack conventions per framework.

·8 minTutorial

Guide: @pyrpc/react from zero to useQuery

Minimal install, api.Provider, useQuery/useMutation, and useUtils for a Vite or CRA-style React app.

·11 minDeep Dive

Next.js RSC: prefetch, dehydrate, and HydrationBoundary

What each server helper does, when you can skip hydration, and why prefetch is for queries not mutations.

·10 minDeep Dive

@rpc.query and @rpc.mutation: why procedure kinds exist

How server-side query/mutation kinds flow through codegen into TanStack hooks without a second import in app code.

·9 minDeep Dive

One api object: Provider, prefetch, and hooks in the same place

Why createNextClient / createReactClient return a single value with procedures, Provider, and server helpers — and why the variable can be named api or client.

·12 minDeep Dive

How to version, edit, and ship pyRPC’s multi-package surface

Synchronized npm @pyrpc/* versions, PyPI independence, what to edit where, and PR/release standards for a multi-package monorepo.

·14 minTutorial

Tutorial: Next.js App Router + TanStack Query with pyRPC

Step-by-step: @rpc.query/@rpc.mutation, createNextClient, RSC prefetch, HydrateClient, and client hooks.

·18 minDeep Dive

Deep dive: framework adapters, TanStack Query, and procedure kinds

Architecture of @pyrpc/react, next, vue, and svelte — one transport, flat DX, query/mutation kinds, and Next.js hydration.

·8 minDeep Dive

Following an RPC Call: From TypeScript Client to Python Function and Back

A step-by-step trace through pyrpc's RPC Call Flow: Proxy interception, HTTP transport, envelope validation, Router lookup, Procedure execution with TypeAdapters, and the error path.

·10 minDeep Dive

A Visual Tour of pyrpc's Architecture

Eight diagrams, seven packages, one framework: a guided walkthrough of pyrpc's architecture from the system landscape down to individual components and dynamic flows.

·8 minDeep Dive

Architecture as Code: Mapping pyrpc with LikeC4

How we turned pyrpc's architecture into version-controlled, interactive diagrams using LikeC4 — and why every framework should do the same.

·8 minDeep Dive

715x faster type generation with the npx daemon

A persistent Node.js daemon replaces per-call npx subprocesses, dropping type regeneration from 3.3s to 4.6ms. How it works, the benchmarks, and the edge cases we handled.

·4 minRelease

v0.7.3 - Django adapter, FastAPI/Flask fixes

A new Django adapter (pyrpc-django-adapter) with native async views, plus an introspection crash fix that affected all adapters when no explicit router was provided.

·10 minRelease

v0.6.0 - Client distribution and package standardization

npx pyrpc sync, postinstall prompt, framework extras (pyrpc-core[fastapi], pyrpc-core[flask]), adapter auto-install, pyrpc.json config, distribution modes, and package standardization.

·9 minDeep Dive

Server mode: type distribution across repositories

How server mode works: the schema endpoint stays in memory, pyrpc never writes to the client filesystem, and the client fetches types on demand via npx pyrpc sync.

·7 minDeep Dive

Workspace mode: what happens when you run pyrpc dev

A step-by-step walkthrough of workspace mode: config resolution, client root validation, migration checks, file watcher loop, dev server startup, and CI compatibility.

·8 minDeep Dive

Distribution modes: workspace and server

Two distribution modes for pyrpc: workspace (monorepo, types written directly to client) and server (separate repos, types fetched via HTTP). When to use each and how they work under the hood.

·7 minDeep Dive

Why save_typescript_client() refuses relative paths

The hidden bug in os.getcwd() fallback paths - why a silent default is worse than a hard error, how the CLI layer resolves paths before calling the API, and the "fail fast on global state" design principle.

·8 minDeep Dive

No pyrpc init needed: designing the integrated setup wizard

Why pyrpc embeds setup inside pyrpc dev instead of a separate init command: fewer context switches, --reconfigure pre-fills defaults, CLI flags skip the wizard entirely, and KeyboardInterrupt exits cleanly.

·9 minDeep Dive

Three deployment architectures for pyrpc

Monorepo, separate repos, and published npm package - how pyrpc's config system and type generation handle all three workflows, and why server-side codegen was built before the client-side npx CLI.

·10 minDeep Dive

Three cases, zero data loss: pyrpc's types migration strategy

What happens when you change client_root in pyrpc.json? Three cases with SHA256 comparison, interactive prompts only when needed, and a clean KeyboardInterrupt path that never leaves half-migrated state.

·8 minDeep Dive

Path resolution in pyrpc: config-relative, not CWD-relative

Why resolving paths against pyrpc.json's directory (not os.getcwd()) is the only correct approach, how the pipeline produces absolute paths everywhere, and why save_typescript_client() enforces the contract at the boundary.

·9 minDeep Dive

pyrpc.json: why we left pyproject.toml behind

Three problems with [tool.pyrpc] in pyproject.toml - fragile writing, ambiguous file ownership, and unclear path semantics - and why a dedicated pyrpc.json file with JSON, not TOML, was the right answer.

·8 minRelease

v0.3.3 - Cleaner types, no more /rpc/rpc, quieter watcher, CORS included

TypeScript autocomplete no longer suggests .rpc, URL normalization prevents double /rpc/rpc, file watcher debounced to 300ms, and the ASGI dev server now sends CORS headers - all following reference patterns from tRPC, Better Auth, FastAPI, webpack, and nodemon.

·6 minRelease

v0.3.2 - Cleaner terminal, smarter prompts, no more :app confusion

Interactive framework picker, simplified entry point, CWD import path fix, and a terminal that shows what matters - no Uvicorn spam, no raw [cyan] markup, no giant Panel boxes.

·4 minRelease

v0.3.1 - Lazy imports, pyrpc_codegen decoupled from CLI

pyrpc_codegen is no longer loaded for version, inspect, serve, pull, or help - only codegen and dev need it. A patch triggered by a stale shim bug.

·5 minRelease

v0.3.0 - pyrpc-cli merged into core, one-command install

pip install pyrpc-core now gives you the runtime, CLI, and codegen in a single command - no separate packages, no extra steps.

·7 minRelease

Why we merged pyrpc-cli back into pyrpc-core

How the circular dependency that motivated a three-package split disappeared - and why we simplified back to two packages for a single-install experience.

·11 minDeep Dive

How to break a circular dependency in Python packaging

Four strategies for breaking circular package dependencies in Python, evaluated through pyrpc’s real-world restructuring — with a step-by-step extraction guide.

·7 minDeep Dive

Windows compatibility in a Python OSS project: what we learned

Unicode crashes on cp1252, LF/CRLF git warnings, path separators, file watcher quirks, and a no-special-chars policy for cross-platform Python OSS.

·8 minDeep Dive

Lazy imports as API contract, not performance hack

Three tiers of CLI commands, the packaging-vs-code dependency distinction, and why lazy imports define capability boundaries — not just startup time.

·9 minDeep Dive

The Better Auth meta-package pattern, adapted for Python

How Better Auth’s npm meta-package inspired pyrpc’s package architecture, and how we adapted it for Python’s packaging constraints.

·7 minDeep Dive

Core → CLI → Codegen: why the dependency direction matters

Why pyrpc-core → pyrpc-cli → pyrpc-codegen is the right dependency direction - and three principles for designing package chains that never tangle.

·8 minDeep Dive

Dev console vs shell: two tools, one job, and the line between them

Why the dev console reads from the parent process (not HTTP), how the shell connects remotely, and the shared REPL UI that bridges them.

·10 minDeep Dive

The circular dependency problem and how pyrpc-cli solved it

How we discovered and solved the circular dependency between pyrpc-core and pyrpc-codegen by extracting pyrpc-cli - with three alternative strategies evaluated and a step-by-step extraction guide.

·12 minRelease

CLI overhaul, model interfaces, and the dev tools we built

Merging pull into codegen, fixing serve, adding the dev watcher and shell REPL, and integrating jsonschema-ts for Pydantic model interfaces.

·14 minDeep Dive

Designing the pyrpc developer console

Threads, subprocesses, and an embedded interactive console - how pyrpc dev combines a dev server, file watcher, type generator, and CLI into one terminal session.

·6 minRelease

v0.2.0 - Type safety, proper async, and @pyrpc/types

The three critical fixes that ship pyRPC v0.2.0: real type generation, working async, and a postinstall-based @pyrpc/types setup.

·8 minRelease

Cleaner codegen, one CLI, and a sharper story

Pattern A CLI, lazy pyrpc-core imports, frontend DX simplified to npm install, cross-language positioning, SECURITY.md rewrite, and Windows cp1252 fixes.

·8 minDeep Dive

Inside the Interactive Demo Sandbox

A deep dive into how the pyrpc playground works - design decisions, architecture, and a comparison with the real pyrpc implementation.

·6 minTutorial

Why pyRPC?

The philosophy behind pyRPC, what tRPC-style typing means for Python backends, and why we built it.

·7 minTutorial

From raw FastAPI to pyRPC

A before-and-after migration guide showing how to convert a traditional FastAPI application to pyRPC - and why you might want to.

·10 minTutorial

Building a full-stack app with pyRPC

A step-by-step tutorial: FastAPI backend, TypeScript React frontend, end-to-end type safety with pyRPC.