Skip to content

TypeScript SDK

TypeScript packages consumed as SDKs or client libraries by other projects.

Charter status

Charter status Value
Maturity Candidate rubric
What this state means Numbered candidate rules carry severity, required evidence, and an exception policy. A versioned rubric can be cut from this page once its promotion criteria are met.
Full rubric Not authored yet. This page is a charter, not a judgeable standard.
Reference implementation vibecodeqa/ref-typescript-sdk (published) — see Reference implementation below.
Blocking promotion Twelve candidate rules carry severity, evidence, and exception terms, and ref-typescript-sdk now exists, is published in the catalog, and carries a self-reported score with a green CI run (#14). Blocking v1: the reference repo's report evidences the required implementation but does not judge R-SDK-1 to R-SDK-12 one by one at a named commit, and no independent assessment of the repo exists.

Maturity states are defined in Standards Authoring. Metadata lives in standards/registry.json.

Full rubric

No full versioned rubric has been authored yet.

Reference implementation

Score evidence Value
Repository vibecodeqa/ref-typescript-sdk (published)
VCQA report A 98/100
Verification self-reported
Assessed commit 2f6a285
Assessed on 2026-08-09
CI run success (2026-08-08)
Independent assessment None published yet. The score above is the reference repo's own claim, not third-party proof.
Catalog entry last verified 2026-08-09

Teaching focus

This standard teaches that an SDK is a compatibility promise, not just a compiled TypeScript package. Choosing this stack means maintaining a small public surface, shipping declarations that match runtime behavior, keeping generated API clients fresh, and giving consumers typed failure modes they can handle without reading implementation code.

Scope

TypeScript packages consumed as SDKs or client libraries by other projects.

Not in scope

  • apps with no exported API
  • private implementation packages
  • untyped JavaScript packages
  • CLIs where the command-line interface is the primary product contract
  • deployed packages that declare an entry point for a host rather than for a consumer — Firebase Cloud Functions codebases and VS Code extensions both declare main, but they publish nothing and are deployed, not imported (#49)

Composes

Upstream references

VCQA-owned rule surface

  • export map and public entrypoint quality.
  • declaration output and declaration/runtime alignment.
  • ESM/CJS and runtime support decisions.
  • API contract freshness.
  • generated client drift detection.
  • typed error model.
  • runtime validation at external boundaries.
  • semantic versioning and compatibility tests.
  • credential boundary and redaction policy.
  • publish artifact and provenance policy.

Detection signals

  • package.json declares both an entry point (exports, main, module) and a types declaration (types, typings, typesVersions) — resolver signal. The entry point alone is not enough: a deployed package has one too. The types declaration is what says the package is meant to be imported.
  • package.json files
  • declaration, emitDeclarationOnly, or declarationMap in tsconfig.json
  • dist/*.d.ts, *.d.mts, or *.d.cts artifacts
  • OpenAPI, JSON Schema, or generator config files
  • generated client directories or checked-in API schemas
  • public Client, Error, Config, Credentials, or TokenProvider types
  • consumer fixture tests, package tarball tests, or matrix tests across TypeScript/module-resolution modes

Combination-born guidelines

  • Export maps and declarations are compatibility gates, not packaging polish.
  • Generated API clients must track the checked-in OpenAPI contract.
  • Runtime errors need a typed model consumers can handle without string matching.
  • TypeScript types describe the SDK API, but OpenAPI/JSON Schema/Zod-style validation must still guard untrusted API responses and user-provided config.
  • ESM/CJS support is a product decision; each advertised condition or entrypoint must have matching JavaScript and declaration files.
  • Credential helpers may make local development easier, but SDKs must not own application secrets or silently read unrelated ambient credentials.
  • SemVer applies to runtime behavior, exported types, module entrypoints, error shapes, and documented side effects.

Candidate rules

  • R-SDK-1: Public entrypoints are intentional. package.json exposes only supported API entrypoints through exports or equivalent metadata, and deep imports into build internals are treated as unsupported.
  • R-SDK-2: Declarations are shipped and checked. Published packages include declaration files for every public entrypoint, and CI verifies declarations by compiling consumer fixtures against the packed artifact.
  • R-SDK-3: Runtime and declaration modules agree. ESM-only, CJS-only, or dual-package support is documented; conditional exports, type, JavaScript extensions, and .d.ts/.d.mts/.d.cts files match Node and TypeScript resolution rules.
  • R-SDK-4: Supported runtimes are explicit. Node, browser, worker, edge, or bundler support is named in docs and package metadata, with tests proving that unsupported runtime APIs are not pulled into supported entrypoints.
  • R-SDK-5: API contracts stay fresh. SDK request and response types derived from OpenAPI or JSON Schema are regenerated or checked in CI whenever the source contract changes.
  • R-SDK-6: Generated client drift fails builds. Generated files are reproducible from checked-in config, generator versions are pinned, and CI fails when generated output differs from the committed API contract.
  • R-SDK-7: External data is validated at runtime. Unknown API responses, webhook payloads, config files, and user-provided JSON are parsed before being exposed as trusted domain types.
  • R-SDK-8: Errors are typed. Consumers can branch on stable fields such as name, code, status, retryable, details, and cause; they do not need to parse human-readable messages.
  • R-SDK-9: Credentials stay at the edge. SDKs accept credentials, token providers, or request-signing callbacks from the host application and redact them in logs/errors; they do not persist raw secrets or search broad ambient locations by default.
  • R-SDK-10: Compatibility is tested as a consumer would use it. CI packs or links the SDK into fixture projects and tests import/require paths, tree-shakable subpaths, declarations, and representative runtime calls across supported TypeScript and Node versions.
  • R-SDK-11: SemVer covers types. Removing exports, narrowing accepted input, changing error codes, changing default side effects, or breaking declaration compatibility is a breaking change even when JavaScript still runs.
  • R-SDK-12: Publish artifacts are minimal and reproducible. files, build output, source maps, declarations, provenance, and release scripts are controlled so consumers receive intended artifacts and no local secrets, fixtures, or generator caches.

Severity and evidence

Severities follow the shared rule contract. Severity belongs to the rule, not to the reviewer.

Rules Severity Escalation
R-SDK-9 blocker Already top severity. An SDK that persists raw secrets or harvests ambient production credentials makes every consuming application unsafe by installing it.
R-SDK-12 high blocker when the packed tarball contains a secret, a local env file, or a credential cache.
R-SDK-2, R-SDK-3 high blocker when the published artifact does not resolve at all for an advertised entrypoint: the package is broken for every consumer on that path.
R-SDK-7, R-SDK-8, R-SDK-11 high blocker for R-SDK-7 when unvalidated API data reaches an authorization or tenant-scoping decision.
R-SDK-1, R-SDK-4, R-SDK-10 medium high when a runtime is advertised in docs or package metadata but never tested.
R-SDK-5, R-SDK-6 evidence-only high when the generated client is stale against the checked-in contract, and blocker when the drift is in an auth, payment, or tenant-boundary path.

Required evidence:

evidence:
  sourcePaths:
    - "src/**"
    - "dist/**"
  configFiles:
    - "package.json"
    - "tsconfig.json"
    - "openapi.yaml or the checked-in API contract"
    - "generator config"
    - ".github/workflows/*.yml"
  ciArtifacts:
    - "packed tarball file listing from a release-path job"
    - "consumer fixture build logs for import and require, across supported TypeScript versions"
    - "generated-client regeneration diff job output"
  runtimeProof:
    - "a fixture project that imports the packed artifact and makes one representative call"
    - "a declaration-resolution check per advertised export condition"
  negativeEvidence:
    - "no secret, .env file, fixture credential, or generator cache in the packed tarball"
    - "no unsupported-runtime API pulled into a supported entrypoint"
  exceptionFormat: "accepted-exception"

CI expectations: compatibility evidence comes from the packed artifact, not the source tree. A job that type-checks src/ proves nothing about exports, types, or conditional declaration resolution, and does not satisfy R-SDK-2, R-SDK-3, or R-SDK-10.

Exception policy

Exceptions use the acceptedException record in the rule contract: owner, scope, environment, reason, compensating controls, evidence, expiry, approval trail. Stack-specific rulings:

  • ESM-only or CJS-only is a documented decision, not an exception. Record it in package metadata and docs; R-SDK-3 then judges consistency with that decision.
  • R-SDK-10 is exceptionable in breadth for an internal SDK — a reduced TypeScript/Node matrix, scoped to the named consuming repositories, with an expiry. It is not exceptionable in kind: at least one consumer fixture must exercise the packed artifact.
  • R-SDK-6 is exceptionable for a hand-maintained client when the generator was abandoned deliberately; the compensating control is a contract-diff check that fails on drift.
  • R-SDK-9 and the secret half of R-SDK-12 are not exceptionable. A published tarball containing a credential is closed by rotating it and republishing, not by an approval.
  • An exception cannot change the archetype. A package whose real contract is a command line is not an SDK with an exception; judge it as Node CLI Internal Tool.

Anti-patterns

  • Publishing dist JavaScript without matching declarations.
  • Allowing consumers to import undocumented dist/internal/* paths.
  • Shipping exports for JavaScript but relying on a single stale top-level types file.
  • Claiming both ESM and CJS support without testing import and require consumers against the published package.
  • Treating generated clients as hand-maintained files with no reproducible generator command.
  • Representing every failure as Error with only a message string.
  • Trusting API responses because the TypeScript type says they should be valid.
  • Loading production tokens from .env, global config, or cloud metadata automatically in a reusable SDK.
  • Making patch releases that remove fields, change error codes, or alter default retries/timeouts in observable ways.

Promotion criteria

This charter can be cut as typescript-sdk/v1 when all of the following are true.

  1. Every candidate rule is rewritten in the rule-contract rule template, with severity, why, evidence, exception, a vcqa scanner or human-review signal, and a good/bad example.
  2. Every candidate rule has been judged against ref-typescript-sdk at a named commit, with the pass or fail recorded. The repo now exists and its score evidence is in compositions.json (#14), which closes half of this criterion; the remaining half is the binding gap, because its report evidences the required implementation without judging R-SDK-1 to R-SDK-12 one by one.
  3. The packed-artifact evidence above is produced by a real job, so the resolution-matrix rules are checkable rather than aspirational.
  4. R-SDK-11's "SemVer covers types" claim has a concrete check — an API-surface snapshot or declaration diff — rather than reviewer judgement alone.
  5. A fresh independent assessment scores this page above the draft band, replacing the dated report linked below.
  6. The registry entry gains a v1 edition with reviewed, next-review, targets, and lifecycle metadata, and the page is rewritten to the authored charter bar in Standards Authoring.

Review cadence

While this charter is a candidate rubric it is reviewed:

  • whenever TypeScript changes module resolution behaviour or declaration emit, which moves R-SDK-3 directly;
  • whenever Node changes exports condition resolution or the supported LTS line;
  • whenever a reference implementation for this stack is created or scored;
  • and in any case no later than six months after the date of the most recent assessment report linked below.

Benefits

  • Cloudflare SaaS example SDK.
  • future VCQA schema/client packages.

Independent Assessment

That report is a dated snapshot of this page on 2026-07-25, before it carried severity, an exception policy, promotion criteria, or a review cadence. It is not rewritten, and its score is not restated here as current; a fresh assessment is a promotion criterion above.