---
title: "Core and language SDKs"
description: "The core is pure TypeScript with zero runtime dependencies; Rust, Python and Go get their own native SDKs that share contracts and data, never code."
section: "architecture"
status: "Planned for 0.4"
spec: "portable-core"
canonical: "https://mainsdk.dev/docs/architecture/core-and-bindings"
updated: "2026-10-28"
---

# Core and language SDKs

> The core is pure TypeScript with zero runtime dependencies; Rust, Python and Go get their own native SDKs that share contracts and data, never code.

Status: Planned for 0.4 · Canonical: https://mainsdk.dev/docs/architecture/core-and-bindings · Updated: 2026-10-28

MainSDK's core is TypeScript from day one: the policy engine, the rule checks, the contract types, crypto, parsers and every interface. It is pure TypeScript with zero runtime dependencies, built on the standard library and the runtime's WebCrypto, Intl and streams (ADR-0066). There is no sidecar, no separate process and no native binary to install.

```mermaid
flowchart TB
  subgraph core["mainsdk (TypeScript)"]
    eng["Policy engine<br/>Cedar evaluator in TypeScript"]
    rules["Rule checks"]
    con["Contract types<br/>generated from TypeSpec"]
    ifc["Interfaces and local drivers"]
  end
  layer["Shared contract layer, data only<br/>TypeSpec contracts, main.yaml, error codes, parity vectors"]
  rust["mainsdk crate (Rust)<br/>phase 5, first"]
  py["mainsdk (Python)<br/>phase 5"]
  go["mainsdk.dev/go<br/>phase 5"]
  core --> layer
  rust -.-> layer
  py -.-> layer
  go -.-> layer
```

## Why TypeScript first

- Agents build most new apps in TypeScript, and one language means one toolchain until the second SDK arrives.
- No binary matrix, no ABI handshake, no install step: `mainsdk` installs and imports like any package, on any platform Node.js 22+ runs on.
- The same code runs on Node.js, Bun, Deno and Cloudflare Workers (spec portable-core), because the core uses WinterTC APIs and keeps `node:*` in runtime adapters.

## The policy engine

The built-in engine evaluates Cedar (`.cedar` files) in TypeScript, in process, with no network call. We check it against Cedar's published integration-test corpus for the subset it supports. A construct it doesn't support fails to load with a named error, never a silent allow. Other engines plug in as drivers (see [policy engine](https://mainsdk.dev/docs/architecture/policy-engine)).

## In the browser

Policy runs on the server by default (`policy.placement: server`). The browser entry of `mainsdk` stays under 150 KB gzipped and contains no policy engine; it asks your server for decisions. If you set `policy.browser.local: true`, the TypeScript Cedar engine loads lazily as a separate chunk, outside that budget. The browser is never the only place a deny is enforced for data or actions the server owns.

## Errors that point at your code

Packages ship built JavaScript with source maps and the TypeScript they point at (ADR-0045), so stack traces point to your source, not SDK internals. `MAINSDK_DEBUG=driver` prints each provider call, redacted.

## Other languages and runtimes

| What | Phase |
| --- | --- |
| TypeScript on Node.js 22+, Bun, Deno and Cloudflare Workers | 1 |
| Rust SDK (`cargo add mainsdk`), for apps, services and endpoint agents; first of the three, may come sooner | 5 (milestone 1.5) |
| Python and Go SDKs | 5 (milestone 1.5) |

Every language gets the same product: AI-native, MCP-native, secure by default, capabilities built in, and token-efficient for coding agents, with an agent skill, a short call grammar and short errors that carry a fix. Each SDK is its own native library, written in its language's idiom with its own releases, docs and skill. No SDK loads another's code: there is no shared core, no FFI and no sidecar (ADR-0075).

What languages share is a thin contract layer of data: the TypeSpec contracts and the wire formats they define, the `main.yaml` schema, the error and finding codes, and golden test vectors exported from the TypeScript reference. Every SDK reads the same `main.yaml`, raises the same codes and verifies the same licences and seals, so apps and tools stay compatible across languages. The vectors are optional parity data each language may adopt; they check results and codes, never API shape. `packages/core` holds the contract sources (TypeSpec and vendored OpenAPI).

## Next

- [Performance budgets](https://mainsdk.dev/docs/architecture/performance-budgets): the limits the core is measured against.
- [Policy engine](https://mainsdk.dev/docs/architecture/policy-engine): how decisions are made.
- [Contracts and versioning](https://mainsdk.dev/docs/architecture/contracts-and-versioning): the ten contracts and how they change.
