> For the complete documentation index, see [llms.txt](/llms.txt)

# How Glotto compares

An SDK is not a typed wrapper around HTTP calls. A good one auto-paginates, retries with
jittered backoff, exchanges auth tokens transparently, surfaces errors as the language's
native exception type, and gives callers compile-time confidence that request shapes are
correct — and it does that across a dozen languages, each with its own idea of "idiomatic."

When you evaluate a generator, two questions decide it:

1. **Is the output idiomatic?** — code your users would have written by hand.
2. **How do you keep every language correct and in parity?** — so a feature isn't silently
   missing in one SDK.

This page answers both, and shows where Glotto sits relative to the alternatives.

## The landscape

Every tool optimizes for something. None of these is "wrong" — they make different trades.

- **Open-source generators (e.g. OpenAPI Generator).** Enormous language coverage, zero
  cost, battle-tested. The trade is output quality: generated code is functional but rarely
  idiomatic, so teams that care about SDK developer experience end up post-processing or
  customizing heavily.
- **Managed platforms (Stainless, Speakeasy, Fern).** Strong, polished output and a
  turnkey experience. The trade is control: you accept the platform's opinion about what
  your SDKs look like, and the pipeline that regenerates them lives in someone else's black
  box.
- **Build-your-own IR frameworks (e.g. oagen).** You parse the spec into a clean,
  fully-resolved intermediate representation and write your own emitters. Maximum control —
  the trade is that you build and maintain the emitters yourself.

**Glotto's bet:** keep the IR-and-emitters architecture that makes output idiomatic, ship
the emitters so you don't build them, and back the whole thing with parity enforcement so
"every SDK has it" is a tested guarantee rather than a hope. Plus the wedge the managed
platforms don't cover: **React Native** as a first-class target, **GitLab/Bitbucket**
alongside GitHub, and a multi-mode **MCP** server including Code Mode.

## Axis 1 — idiomatic output

The insight every serious generator shares is that you don't template raw YAML. You parse
the spec **once** into a normalized, fully-resolved intermediate representation — all the
`$ref` chains, schema composition, and OpenAPI quirks handled centrally — and then each
language's emitter consumes that clean data model and makes **real per-language decisions**.

In Glotto the IR is [`@glotto/core-ir`](/docs/glotto-ir): a typed model that carries
optionality, auth schemes, pagination strategy, retry config, and per-language naming as
first-class fields. The emitters consume it and decide, idiomatically:

| The IR says… | Python emits | Go emits | TypeScript emits |
|---|---|---|---|
| an **optional query param** | a keyword arg defaulted to `None` | a pointer field on the params struct (`*string`) | an optional property (`name?: string`) |
| a **`oneOf`** | a discriminated union | a type with a discriminator check | a discriminated union narrowed on the tag |
| a **documented 4xx/5xx** | an `ApiError` subclass | an error type with `errors.As` unwrap | an `ApiError` subclass |

Those aren't template substitutions — they're decisions encoded in hand-written emitters,
which is exactly why the output reads like code a person wrote. The difference from a
build-your-own framework is that **Glotto ships the emitters** for every supported language.

## Axis 2 — code quality and cross-language parity

Idiomatic output is table stakes. The harder problem — the one that decides whether you can
trust a multi-language generator — is keeping every language **correct** and **in parity**,
so a capability shipped for TypeScript isn't quietly missing in Dart.

Glotto enforces that three ways, in CI, on every change:

- **Fresh-compile verification.** The [`@glotto/compile-verification`](/docs/glotto-ir)
  harness fresh-generates each SDK from the IR and **compiles / type-checks it in its target
  language's toolchain** — not "it rendered," but "it builds."
- **Cross-language contract tests.** One [contract manifest](/docs/pagination) of request/response
  scenarios is replayed by a per-language runner for **every** SDK against a mock server,
  asserting each language sends the same request and returns the same value. Behavioral
  parity, checked across languages from a single source of truth.
- **Golden + drift gates.** Every engine's output is byte-locked by golden tests, and a
  dogfooded drift detection fails the build if committed output drifts from what the
  current generator produces.

### The feature matrix — every SDK, every language

The [platform plan's §3.1.2 feature matrix](/docs/retries) is a contract: a capability listed
there must exist in **every** generated SDK. As of the link-header-pagination and
v2-timeout parity closures, all 13 SDK languages — TypeScript, React Native, Python, Go,
Java, Kotlin, C#, PHP, Ruby, Swift, Rust, Dart, and Elixir — satisfy it:

| Capability | Across all 13 SDKs |
|---|---|
| Typed resources & methods | ✅ |
| Auth (Bearer, API-key, OAuth2 + PKCE) | ✅ |
| Retries with jittered exponential backoff | ✅ |
| Per-client timeouts (connect + overall) | ✅ |
| Pagination — cursor, page, offset, **link-header** | ✅ |
| SSE streaming with cancellation | ✅ |
| Webhook verification (HMAC / Standard / Stripe) | ✅ |
| File uploads (multipart) | ✅ |
| Polling helpers (`waitFor`) | ✅ |
| Telemetry hooks | ✅ |
| Rich types (discriminated unions, enums, nullable distinguished from optional) | ✅ |
| Typed `ApiError` hierarchy | ✅ |
| Per-method snippet emission | ✅ |

The surface differs idiomatically by language — async iterators in TypeScript, generators in
Python, channels in Go — but the capability is the same everywhere, and the contract runners
prove it.

## More than SDKs

The same IR fans out beyond client SDKs: an [Astro documentation site](/docs/generated-docs-site)
with per-language snippet tabs, a multi-mode [MCP server](/docs/mcp-server) (including Code
Mode), and a Terraform provider — all regenerated together when your spec changes.

## When Glotto is the right fit

- You want **idiomatic, owned** SDKs without writing emitters yourself.
- You ship to **React Native** and want a first-class target, not a browser-TS approximation.
- You live on **GitLab or Bitbucket**, not only GitHub.
- You want **parity you can prove** — compile-checked, contract-tested, drift-gated — rather
  than a vendor's word for it.

Already on Stainless? See the [migration guide](/docs/migrate-from-stainless) — Glotto's
SDK languages are a superset, and [migrating from Stainless](/docs/migrate-from-stainless)
converts your config in one command.
