Blog
Design notes, deep dives, and updates from the pyrpc team.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
Why pyRPC?
The philosophy behind pyRPC, what tRPC-style typing means for Python backends, and why we built it.
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.
Building a full-stack app with pyRPC
A step-by-step tutorial: FastAPI backend, TypeScript React frontend, end-to-end type safety with pyRPC.

pyRPC