sdkscore.

Methodology

SDKScore is a compiler-graded benchmark. Everything below is stated so that a hostile reader can reproduce a score and prove us wrong. Where the method is weak, it says so.

01What is measured

One question: when an AI coding agent is asked to write a first integration against a given SDK, does the code it produces type-check against that SDK's real, published types?

That is not the same as "is this SDK good", and it is not a measure of the agent's general ability. It is a proxy for one specific thing that has become expensive: an SDK whose surface confuses agents produces broken first drafts, and the cost lands on the SDK's own support channel.

02Version pinning

Each SDK gets a throwaway npm project containing nothing but that package at an exact pinned version (no ranges), TypeScript, and a fixed tsconfig.json. Types are read from the installed package. Never from documentation, never from a hand-written stub.

{
  "compilerOptions": {
    "strict": true,
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "noEmit": true,
    "skipLibCheck": true,
    "types": ["node"]
  }
}

skipLibCheck is on deliberately: we grade the agent's file, not pre-existing type errors inside the SDK's own .d.ts files. The pinned version and the TypeScript version are recorded in every results.json, so a score always refers to a specific pair.

03Tasks and prompts

Each SDK has four tasks. Tasks are chosen to be the things a developer actually writes in the first week: auth, the main write path, the main read path, and one thing that is easy to get subtly wrong (webhook verification, pagination, streaming).

Design constraint

A prompt that names the exact method under test would measure transcription, not integration. If a task can only be passed by guessing an undocumented symbol, that task is a bad task and gets removed. We do not keep it as a gotcha.

04Generation

Every sample is produced under identical conditions:

Generation conditions applied identically to every sample.
ConditionSetting
modeheadless, non-interactive; no human in the loop
attemptsone per task; no retries, no self-repair loop
toolingwrite the file; the agent cannot run the compiler or the grader
networkno live docs fetch during generation
contextthe task prompt plus the project's package.json
outputa single TypeScript file, graded exactly as written

The one-attempt rule matters. Agents with a compile-and-fix loop score far higher on everything, which measures the harness rather than the SDK. SDKScore deliberately grades the first draft, because that is what tells you whether your API surface is guessable.

05Grading

A task passes only if both checks pass:

  1. Compilation. tsc --noEmit over the generated file with the config above, against the pinned SDK's real types. Any error attributable to the generated file fails the task. Every error string is published.
  2. Pattern checks. A small, published set of required and forbidden string/regex patterns per task. See below.

Grading is a pure function of the generated file. Rerunning the grader on the same file always yields the same verdict. There is no partial credit inside a task: it compiles clean and satisfies its patterns, or it fails.

06Pattern checks

The compiler misses one important failure mode: code that type-checks but uses an API the vendor has verifiably deprecated. Pattern checks cover exactly that gap, under strict rules:

Every pattern failure on the leaderboard is shown verbatim, with the reason attached.

07Scoring and bands

Per model: score = round(100 × passed ÷ total). With four tasks the per-model score is one of 0, 25, 50, 75, 100. The scale is deliberately coarse: four samples do not support finer resolution. The overall score is the unweighted mean across models. Tasks are equally weighted; there are no bonus points.

90–100 green 75–89 yellowgreen 60–74 yellow below 60 red

Trend is the change in overall score versus the previous published run. A trend can move because the agent changed, because the SDK released a new pinned version, or because a task was added. The run record says which.

08Why there is no LLM judge

No model grades anything, anywhere in this pipeline. Not as a judge, not as a tie-breaker, not to "sanity check" a failure.

The cost of this choice is coverage, and it is stated plainly in limitations.

09Contesting a score

If a task is unfair, the score is wrong, and we want to know. Open a public issue on the benchmark repository with the SDK id, the task id, and the model. Useful grounds:

Disputes are handled in public and the outcome is recorded. Accepted disputes change the task suite, and the whole matrix is rerun. Never a single SDK in isolation. Vendors get no private channel to adjust their own numbers, and there is no way to pay to be removed from the board.

10Limitations

Read this before quoting a number

A score is a lower bound proxy, not a verdict on your SDK's quality.

11Reproducing a run

The harness, the task suite, and every published results.json are open. To check a single score by hand:

npm i <package>@<pinned-version> typescript
# paste the prompt from config/sdks.json into your agent, headless, one attempt
npx tsc --noEmit src/index.ts

If your verdict differs from ours, that is a bug report and we want it. Every results.json carries generatedAt, the harness versions, and the pinned SDK version needed to reconstruct the exact conditions.

← Back to the leaderboard