Turn any API into a typed, resilient function.
An open-source TypeScript library that turns one API endpoint into a typed, resilient function — validated, retried and observable by default, no server or codegen required. Built for developers integrating third-party APIs, and for the AI agents that call them.
4,400+
npm downloads in the last 30 days
0
runtime dependencies
~25 kB
min+gzip for the whole entry, budget enforced in CI
90%
line coverage

At a glance
- Type
- My own open-source library
- Scope
- Everything: the core stitchapi library, all 36 packages around it in packages/, the docs site, and the release pipeline that publishes it all to npm.
- Status
- Live — 0.7.0 on npm, 1.0 in release candidate · as of 24 Sep 2026
- Timeline
About a week to the first 1.0 release candidate · Jun 2026
Rebuilt from the ground up; the first version shipped in 2024
Latest 1.0.0-rc.7 on npm, 1 Aug 2026
- Platforms
- Node.js 18.18+
- Source code
- Source on GitHub (opens in a new tab)
- Try it
- Try the playground (opens in a new tab)
npm install stitchapi@rc - Stack
The challenge
Most projects end up with a src/api/ folder of thin fetch wrappers, and everything that actually makes an integration reliable — auth lifecycle, retries, rate limits, response validation, drift detection — gets re-implemented at each call site and rots independently. The failures concentrate at the boundary: a vendor renames a field with no version bump, and health checks stay 200 OK while consumers quietly parse garbage. Handing the call to an AI agent instead of a human does not remove the problem — it hands opaque bytes to something that needs a validated, structured result even more.
- Silent schema drift — a vendor renames or restructures a field with no version bump, and compile-time types cannot catch it; it surfaces as a downstream undefined
- No way to observe a third party’s health from outside — the API can return 200 OK while it is not working correctly
- Auth lifecycle: token-refresh races, key rotation, cookie jars, and soft "200-but-actually-a-login-page" walls
- Reliability: rate limits, latency spikes and partial outages need backoff, Retry-After handling and circuit breaking that most integrations never get around to writing
- No uniform primitive across HTTP, GraphQL, streaming, shell and LLM calls, so the failures concentrate in the glue code between them
The constraints
StitchAPI had to stay a library a team drops into an existing codebase, never a platform they adopt or a dependency they have to trust blindly.
- Zero runtime dependencies, with a bundle-size budget enforced in CI, not just an aspiration
- Browser-first: the call path stays free of node:* imports and unguarded process.env reads, so a stitch runs wherever fetch does
- No side effects by default: throttle counters, cookie jars and token caches stay in-memory and process-local unless a store or trace sink is opted in
- No vendor lock-in: fetch, Zod and the in-memory store are defaults, not requirements — every seam ships a conformance kit so a swapped implementation can prove compliance
- Third-party service names stay out of public docs and artefacts — neutral archetypes only
The solution
I designed one primitive — a stitch — so an endpoint becomes a typed, resilient function instead of throwaway glue code, with auth, retries, caching and drift detection declared as configuration on it rather than hand-rolled per call. A service with more than one endpoint is a seam: it shares that configuration and one runtime — one throttle bucket, one store, one trace sink — across every endpoint that belongs to it. Each of the decisions below went through a written design review before it shipped.
Schema-anchored drift, not a snapshot
A snapshot baseline couldn’t tell real drift from ordinary response variance, and it conflated two different questions: has the vendor changed, or will my code break? Anchoring drift to the schema I declare answers only the second, honest question, with no snapshot to generate or maintain.
A seam binds the auth principal at construction
Sharing runtime as well as configuration meant a cookie-backed session could leak from one user to another. Binding the principal in trusted code the caller can never reach makes per-user credentials safe to share without opening an impersonation hole.
Cache keys are derived, never author-supplied
A key the caller — or an agent — authors by hand can drift out of sync with the request it is meant to name. Deriving the key from the resolved request, with the principal folded in, makes the cache correct by construction and safe enough to bring request coalescing back after an earlier design had ruled it out.
Non-HTTP calls run inside the same resilience chain
A shell command or an LLM call that bypassed retry, throttling and tracing would silently lose all of it. One transport-replacing hook at the exact call site keeps every surface uniform, and the shell surface stays injection-proof by construction — a static binary and an argv array, never a shell string to escape.
Architecture
stitch()
One endpoint, one typed callable — auth, retries and validation declared on it
seam()
A shared base, auth and budget for every endpoint in a service
Validation & drift
The output schema is the contract; soft drift is reported, hard breaks throw
Resilience
Retry with backoff, proactive throttle, a circuit breaker, layered timeouts
Auth as a boundary
Bearer, API key, cookie session or OAuth2 — secrets resolve at call time
Response cache
A derived, principal-scoped key; refuses to cache a shape it cannot fingerprint
HTTP
The default surface — a JSON-over-HTTP call
GraphQL, SSE, streams
Peer surfaces on the same engine, each its own subpath import
LLM & shell
A provider-mapped chat call and a static, argv-array local command
Function
import and call it in-process
CLI
`stitch run` streams every event as JSON lines
HTTP endpoint
`stitch serve` exposes the same definition over HTTP
MCP
One code-mode tool for an agent, not one per endpoint
I build — you own
Built to hand over
StitchAPI is public, so this is what a handover actually looks like here, not a promise: the code, the decisions behind it, and everything you’d need to run and extend it without me.
- View (opens in a new tab)
Code & licence
The full source and commit history are public on GitHub under the permissive Apache-2.0 licence.
- View (opens in a new tab)
Documentation
The documentation site itself — guides, concepts, surfaces reference, an agent guide and a live playground — ships from apps/docs in the same repo, not as a separate wiki.
- View (opens in a new tab)
Tests & coverage
A coverage floor enforced in CI on every PR — statements, branches, functions and lines all gated — on top of a green multi-job verify suite covering types, lint, exports, bundle size, browser e2e and MCP end-to-end.
- View (opens in a new tab)
Release pipeline
Every release publishes straight from GitHub Actions over OIDC trusted publishing — no long-lived npm token — gated on the full verify and browser e2e suite, and ships a signed build-provenance attestation plus SPDX and CycloneDX SBOMs with the GitHub release.
- View (opens in a new tab)
Decision records
21 accepted architecture decision records in docs/adr/ — plus 5 more kept on the record as proposed, rejected or superseded — e.g. why cache keys are derived rather than author-supplied (ADR 0003), or why fleet-wide concurrency uses a lease, not a counter (ADR 0025).
- View (opens in a new tab)
OpenSSF Scorecard
The repo is scored publicly by OpenSSF Scorecard on every push — a third party’s read of its supply-chain security practices, not my own claim.
Results
StitchAPI is public on GitHub and published to npm as stitchapi, already pulling 4,400+ downloads a month while still at release-candidate stage, ahead of a stable 1.0. The core runtime is feature-complete and zero-dependency, already running in production in 2 projects, alongside a companion ecosystem of framework and store integrations and a documentation site with a live in-browser playground.
33
companion integration packages
as of 24 Sep 2026
4
front doors to one definition
as of 24 Sep 2026
2
production projects already running it
as of 24 Sep 2026
What’s next
The core is feature-complete at release-candidate stage and covered by a green, multi-job CI gate. I’m soaking it in real production use before stamping a stable 1.0.0, taking feedback as it comes in.
Have a similar project in mind?
I’ll build it and hand it over: the code, the docs and the accounts are yours.
Discuss a project

