ORXA: LLM-SDK vs the Official Provider SDKs
Comparing @combycode/llm-sdk with the official TypeScript SDKs:
openai, @anthropic-ai/sdk, @google/genai, and xai-sdk.
The thesis
The official SDKs are excellent at what they do: give you a fully-typed, up-to-the-day client for ONE vendor. The cost of that focus is fragmentation. Add a second provider and you immediately deal with three incompatible API shapes, three client construction patterns, three ways to extract text, and zero shared cost or observability primitives.
ORXA: LLM-SDK is the adapter layer that hides this fragmentation without adding a network hop or a runtime dependency. Some of these capabilities do exist elsewhere — OpenAI's Agents SDK has guardrails and human-in-the-loop, Google's ADK has agent tooling, and OpenAI and Google each ship their own retrieval — but always provider-locked, in a separate framework. ORXA unifies all of it (RAG, guardrails, HITL approval, permission policies, pre-flight cost estimation) across every provider, direct, in one zero-dependency package.
The API shape problem
Each provider chose a different request/response contract:
| Provider | Request shape | How to read text out |
|---|---|---|
| OpenAI (Responses API) | input: string | ResponseInputItem[] | r.output_text |
| Anthropic (Messages API) | messages: [{role, content}] | r.content.filter(b => b.type==='text').map(b => b.text).join('') |
| Google (generateContent) | contents: string | Content[] | r.text |
| xAI (native) | client.chat.create(...).sample() | r.message |
| ORXA: LLM-SDK (any provider) | prompt: string | result.text |
Capability table
| Capability | ORXA: LLM-SDK | OpenAI SDK | Anthropic SDK | Google SDK |
|---|---|---|---|---|
| Multi-provider, one interface | yes | no | no | no |
| Per-call $-cost + budgets | yes | tokens | tokens | tokens |
| Observability (OTel), all providers | yes | Agents SDK | no | no |
| Rate-limit queue + retry | queue + retry | retry only | retry only | retry only |
| Runtime dependencies | 0 | 0 | 2 | 4 |
| Unified media gen (image/audio/video) | yes | per-provider | no | per-provider |
| Built-in MCP client (no extra dep) | yes | hosted only | hosted only | extra dep |
| Unified RAG across providers | yes | OpenAI only | no | Google only |
| Agent guardrails | yes | Agents SDK | no | ADK |
| HITL approval (pause/resume) | yes | Agents SDK | no | ADK |
| Pre-flight cost estimate | yes | no | no | no |
Notes: "tokens" = the completion response returns token usage; computing per-call $ is on you (ORXA does it automatically — provider cost field for xAI/OpenRouter, else a bundled catalog). "Agents SDK" / "ADK" = present only in OpenAI's Agents SDK / Google's ADK — provider-locked, separate frameworks. "retry only" = automatic retries, but no per-provider rate-limit queue. Dependency counts are exact. Browser support is omitted deliberately: all of these run client-side (OpenAI/Anthropic via dangerouslyAllowBrowser, Google has a documented browser path), with the same key-exposure caveat — so it is not a differentiator.
MCP: four stories vs one (scenario 29)
| Provider | Approach | Extra dependency |
|---|---|---|
| OpenAI | Hosted: hand a URL in tools — their servers call the MCP server | none |
| Anthropic | Hosted: mcp_servers + tools + beta header | none |
| Client-side: install @modelcontextprotocol/sdk, build transport + Client | @modelcontextprotocol/sdk | |
| ORXA | Client-side: connectMcp() built-in, works with stdio + private servers | none (built in) |
The hosted approach (OpenAI, Anthropic) works for public URLs only. It cannot reach a local stdio server, a company-internal server, or any server requiring custom transport. ORXA: LLM-SDK is client-side with zero extra deps.
When to choose the official SDKs instead
- You will only ever call one provider, now and forever.
- You need the absolute bleeding edge of a provider's API on the day it ships — the official SDK may expose a new parameter before we do.
- You need Python or Rust today (our ports are planned, not yet shipped).
- You are deeply integrated with provider-platform features (OpenAI Assistants object storage, Anthropic Workspaces, Google Vertex agents) that have no cross-provider equivalent to abstract.
Migration
See the getting started guide and the migration
guides (shipping with full docs in Phase 2). The pattern is the same in every case:
replace the provider client construction and the call site with complete()
or createLLM(); the rest of your code stays the same.