Stable

openpkg-tsryanwaits/openpkg-ts

A machine-readable standard for package APIs

GitHubDemo ↗

Problem
TypeScript packages have no OpenAPI-style spec — read the source, or hope.
Standard
OpenPkg is the spec, hosted at openpkg.dev; openpkg-ts is its TypeScript reference implementation.
Extract
extractSpec() gives you the full public API as a typed spec.
Output
Functions, types, interfaces, generics — resolved JSON out.
Agents
Primitives first: extractSpec, diffSpec, recommendSemverBump — the CLI is a thin wrapper over the same SDK.
The Problem

No OpenAPI for TypeScript

REST APIs have OpenAPI. GraphQL has introspection. TypeScript packages have... nothing. You want to know what a package exports? Read the source. Grep through node_modules. Hope the docs are current.

Terminal
# How do you know what lodash exports?
cat node_modules/lodash/package.json
# exports field? Maybe. Maybe not.
ls node_modules/lodash/*.js | wc -l
# 615
grep "export" node_modules/lodash/*.js
# Good luck.
Extract It

One Function Call

openpkg extracts the complete public API surface from any TypeScript package. Functions, types, interfaces, classes. Parameters, return types, generics. JSON Schema out — ready for agents, tooling, whatever needs to understand your API.

extract.ts
import { extractSpec } from '@openpkg-ts/sdk';
const { spec, diagnostics } = await extractSpec({
entryFile: './src/index.ts',
});
The Output

A Typed Spec, Not Prose

An OpenPkg document — JSON conforming to the versioned spec at openpkg.dev, every public export described. Types resolved. Generics expanded. Feed it to an LLM. Generate documentation. Build type-safe wrappers.

spec.json
{
"name": "lodash",
"version": "4.17.21",
"exports": {
"functions": [
{ "name": "map", "params": ["arr", "fn"], "returns": "R[]" },
{ "name": "filter", "params": ["arr", "pred"], "returns": "T[]" }
// ... 309 more
],
"types": 48,
"interfaces": 23
}
}
Built for Agents

Primitives First

Pure functions at the core: extractSpec, diffSpec, recommendSemverBump, validateSpec. An agent doesn't need to shell out and parse stdout; it imports the function and gets a typed result back. The CLI is a thin wrapper over the same SDK — spec, docs, list, diff — and ships a generate-docs agent skill.

diff.ts
import { diffSpec, recommendSemverBump } from '@openpkg-ts/spec';
const diff = diffSpec(oldSpec, newSpec);
// { added, removed, breaking, docsOnly }
const { bump, reason } = recommendSemverBump(diff);
// bump: 'major' | 'minor' | 'patch'
Get Started

Three Packages

sdk for extraction, spec for validation and diffing, cli for humans — a thin wrapper over the sdk. Point extractSpec at any entry file and get a typed spec back, no config.

npm install @openpkg-ts/sdk @openpkg-ts/spec