Key Takeaways

- Temporal's SDK team wrote 70,000 lines of Rust once instead of replicating complex state machine logic in 8 languages
- FFI boundaries, async bridging, and memory safety are the key technical challenges when exposing Rust to other languages
- WebAssembly is emerging as a cleaner alternative to native extensions for cross-language SDK architecture
Writing the same business logic seven times in seven languages is a bad idea. Spencer Judge, who leads the SDK team at Temporal, has a slide to prove it: a state machine diagram backed by 800 lines of code, part of a 70,000-line repository that must live in every SDK Temporal ships. His solution? Write it once in Rust, then build thin language-specific layers on top.
Judge presented this architectural pattern at QCon San Francisco, walking through the practical decisions that shaped Temporal's polyglot SDK strategy. The talk offers a blueprint for any engineering team facing the same multiplication problem.
Why Temporal couldn't avoid fat SDKs
Temporal is a durable execution platform. Users write workflows in their language of choice, and Temporal makes those workflows resilient. The catch: durability guarantees require complex client-side logic. Making an RPC call for every tiny decision wouldn't scale, so the SDK has to be thick.
That thickness is the problem. Temporal supports Go, Java, Python, TypeScript, .NET, PHP, Ruby, and more. Maintaining identical behavior across all of them, with separate implementations, would mean duplicating thousands of lines of subtle state machine code. Bugs would diverge. Features would lag. Testing would multiply.
Judge showed the audience a diagram of just one component, a "local activity," with its 800 lines of backing code. Then he zoomed out: the full state machine layer is about 7,000 lines, sitting inside a 70,000-line repository. "Who would want to write this seven times?" he asked. No hands went up.
The Rust core pattern
Temporal's answer is a shared core written in Rust. All the complicated durability logic lives there. Each language SDK wraps that core through a foreign function interface (FFI), exposing idiomatic APIs to users without reimplementing the hard parts.
Rust fits this job well. Its ownership model provides memory safety without a garbage collector, which matters when your code crosses into runtimes managed by Python's GIL or Java's JVM. Rust compiles to native code, so performance stays predictable. And the language's type system catches errors at compile time that would otherwise surface as subtle bugs in production.
The pattern isn't unique to Temporal. Discord rewrote parts of their Python stack in Rust for similar reasons. Signal's encryption library uses a Rust core with bindings for iOS, Android, and JavaScript. The approach scales wherever complex logic must behave identically across language boundaries.
The hard parts: FFI, async, and memory
Judge didn't pretend this is easy. Three challenges dominate:
- FFI boundaries: Crossing from Rust into Python or TypeScript means flattening Rust's rich types into C-compatible primitives, then rebuilding them on the other side. Every boundary is a place for bugs to hide.
- Async bridging: Rust's async model doesn't map cleanly to Python's asyncio or JavaScript's event loop. The SDK team had to translate between concurrency models without introducing deadlocks or race conditions.
- Memory safety: Rust doesn't use a garbage collector. When the core hands memory to a language with GC, ownership rules get murky. Leaks and double-frees lurk in poorly designed handoffs.
Native extensions, the traditional solution for embedding compiled code in interpreted languages, add their own pain. They're platform-specific, require separate build pipelines, and often break when the host language upgrades. Temporal ships pre-built binaries, but supporting every OS and architecture is a maintenance burden.
WebAssembly as the next step
Judge flagged WebAssembly as a potential simplification. Instead of compiling Rust to native code for each platform, you compile once to Wasm and run it inside any host that supports the WebAssembly runtime. Node.js, browsers, and even some server-side runtimes can execute Wasm with near-native speed.
The appeal is clear: fewer build targets, simpler distribution, and a sandboxed execution model that sidesteps some memory safety concerns. The tradeoff is maturity. Wasm's interface types proposal is still evolving, and performance in heavy async workloads lags native code. But for teams starting fresh, it's worth evaluating.
When this pattern makes sense
Not every SDK needs a Rust core. If your logic is simple, if you only support two languages, or if your team lacks Rust experience, the upfront cost may not pay off. But the calculus shifts when:
- The core logic is complex enough that maintaining parity across languages is painful.
- You're targeting four or more languages.
- Correctness matters more than velocity. Financial systems, encryption, and workflow orchestration fall here.
- Your team can invest in the FFI plumbing once and amortize it over years.
Temporal fits all four criteria. Most teams won't, but the ones that do have a proven model to follow.
Logicity's Take
The Rust-core pattern is a forcing function for API design discipline. Because every public function must cross an FFI boundary, you can't cheat with language-specific hacks. That constraint produces cleaner interfaces. Teams considering this approach should evaluate alternatives too. Mozilla's UniFFI automates much of the binding generation. Nickel and Cap'n Proto handle cross-language serialization. For Wasm-first builds, Extism and Wasmer offer higher-level abstractions. Temporal's stack is custom-built, but the ecosystem is catching up.
Frequently Asked Questions
What is a polyglot SDK?
A polyglot SDK provides the same functionality across multiple programming languages. Users interact with idiomatic APIs in their language while the underlying logic is shared, often through a compiled core or server-side service.
Why use Rust instead of C for a shared SDK core?
Rust offers memory safety guarantees that C lacks, reducing the risk of crashes and security vulnerabilities when code crosses language boundaries. Its type system also catches errors at compile time.
How does Temporal's Rust core communicate with Python or Java?
Through foreign function interfaces. The Rust code exposes C-compatible symbols that each language's runtime can call. Data crosses the boundary as primitive types or serialized bytes.
Can WebAssembly replace native FFI for cross-language SDKs?
Partially. Wasm simplifies distribution and sandboxes execution, but its interface types are still maturing. Performance in async-heavy workloads can lag native code.
What are alternatives to building a custom Rust core?
Mozilla's UniFFI generates bindings automatically. gRPC or similar RPCs move logic to a sidecar service. For simpler cases, code generation from a shared specification works.
Need Help Implementing This?
Planning a polyglot SDK or evaluating Rust for your core infrastructure? Logicity connects engineering teams with consultants who specialize in cross-language architecture and FFI design. Get in touch to discuss your stack.
Source: InfoQ
Manaal Khan
Tech & Innovation Writer
Produced with AI assistance and reviewed by the Logicity editorial team. Learn more in our Editorial Policy.
Related Articles
Browse all
GitHub Copilot CLI: What Business Leaders Need to Know
GitHub's AI-powered command line interface is changing how developers work, with early adopters reporting significant productivity gains. Here's what decision-makers should understand about this tool's business impact and whether it's worth the investment for your engineering team.

URGENCY: IT-Tools Revolutionizes Development with Unified Platform - The New Stack
IT-Tools is changing the game for developers by bringing numerous useful tools into one convenient location. According to The New Stack, this platform is a must-have for any development team. We dive into the details of what makes IT-Tools so special and how it can benefit your workflow.

SURPRISING TAKE: Why Agentic Coding Is Not a Threat But a Catalyst for Developer Growth
The coding landscape is evolving with agentic coding, a shift that's both exciting and intimidating for many developers. We explore why embracing this change can lead to unprecedented growth and innovation. By understanding the core of agentic coding, developers can position themselves at the forefront of the tech revolution.

SURPRISING TAKE: Experienced Open-Source Developers Are Not As Productive With Early-2025 AI As You Think
We dive into the impact of early-2025 AI on experienced open-source developer productivity, exploring the challenges and opportunities that come with AI adoption. According to McKinsey, AI can increase productivity by up to 40%, but is this true for experienced open-source developers? We examine the data and expert insights to find out.


