Skip to content

PATTERN Cited by 1 source

API contract first across three languages

Problem

You're designing an API that must be implemented in three languages simultaneously — TypeScript (RN), Swift (iOS), Kotlin (Android). Each language has different conventions:

  • TypeScript: type unions, optional params, Promise returns.
  • Swift: @objc protocols, completion-handler callbacks, optional closures, error types.
  • Kotlin: interfaces, suspend functions or coroutines, nullable types.

Starting implementation before the contract is agreed means:

  • You'll discover mid-implementation that one language can't honour a design decision made by another (e.g. a TS type union doesn't map cleanly to an @objc protocol).
  • You'll redo work that's already landed.
  • Tests can't be written to a shared contract because there isn't one.

Pattern

Define the contract in all three languages before implementation starts. Specifically:

  1. Draft the TypeScript interface — most flexible typing; good starting point.
  2. Translate to Swift protocol (with @objc) — catches issues with optional types, generics, union types.
  3. Translate to Kotlin interface — catches nullable vs non-nullable, suspending vs blocking conventions.
  4. Walk through each method + callback together — confirm semantics align across all three.
  5. Agree on error types and edge cases across languages before any implementation.
  6. Only now start implementing — each language's impl writers can work in parallel against a frozen contract.

Why upfront

Zalando makes this an explicit lesson-learned in their 2025-10 post (sources/2025-10-02-zalando-accelerating-mobile-app-development-with-rendering-engine-and-react-native):

"Especially when combining three environments into one (TypeScript, Swift and Kotlin) it's crucial to first properly define these API contracts and ensure that all involved environments are compatible with this contract as early as possible. Otherwise, you run into challenges where the API design might not be feasible on all platforms, requiring you to undo work that has already been done."

The lesson comes from doing it wrong the first time — the article frames it as "getting there was not an easy step and required a proper process." Contract-first is the process they converged on.

This is a specific application of the API-first principle (design the API before the implementation) scaled up to three simultaneous languages. The multi-language aspect makes it strictly harder than API-first for a single language — contract drift compounds across language boundaries.

When to reach for this pattern

  • Any three-language API contract (TypeScript + Swift + Kotlin, commonly at the RN-native boundary).
  • Any contract where one of the languages has stricter expressiveness constraints (@objc protocols, for example) — plan the subset first.
  • Any contract that will be implemented by multiple teams in parallel — frozen contract reduces integration pain.

When not to

  • Single-language APIs — standard API-first discipline covers it.
  • Very small contracts (one method, no callbacks) — the overhead of formal three-language review may not pay off.

Seen in

Last updated · 507 distilled / 1,218 read