npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

api-alchemy

v0.2.0

Published

Automatically generates TypeScript types and schemas from real API traffic during development.

Readme

api-alchemy

Automatically generates TypeScript types and schemas from real API traffic during development.

Features

  • 🚀 Zero Configuration: Works out of the box with minimal setup
  • 📡 Fetch Interception: Wraps native fetch to capture responses
  • 🔄 Schema Inference: Automatically infers JSON schemas from responses
  • 🧬 Schema Merging: Evolves schemas as new response variations appear
  • 📝 TypeScript Generation: Generates clean, type-safe interfaces
  • 💾 Persistence: Saves schemas and generated types to disk
  • Non-blocking: Inference runs asynchronously without blocking requests

Installation

npm install api-alchemy

Quick Start

Using Fetch Wrapper

Wrap your fetch call to start capturing API responses:

import { instrumentFetch } from 'api-alchemy';

// Instrument fetch globally
global.fetch = instrumentFetch(fetch);

// Use fetch normally - types are generated automatically
const response = await fetch('https://api.github.com/users/torvalds');
const user = await response.json();

As your application runs, generated types appear in .api-alchemy/generated/:

// Example: .api-alchemy/generated/get-users-id.ts
export interface GetUsersIdResponse {
  id: number;
  login: string;
  avatar_url: string;
  type: string;
  name?: string;
  company?: string;
}

Configuration

import { startApiScribe } from 'api-alchemy';

startApiScribe({
  outputDir: './api-types', // Default: ./api-types
  enabled: process.env.NODE_ENV === 'development'
});

How It Works

Pipeline

HTTP Request
     ↓
Fetch Wrapper (Interception)
     ↓
Extract JSON Response
     ↓
Schema Inference (detect types & structure)
     ↓
Schema Merge (combine variations)
     ↓
TypeScript Code Generation
     ↓
Save to Disk (.api-alchemy/generated/)

Endpoint Normalization

Dynamic URL segments are automatically converted to placeholders:

https://api.github.com/users/123       → GET /users/:id
https://api.github.com/repos/foo/bar   → GET /repos/:owner/:repo
https://api.example.com/items/abc123   → GET /items/:id

These become type names:

GET /users/:id                 → GetUsersIdResponse
GET /repos/:owner/:repo        → GetReposOwnerRepoResponse

Schema Merging

When the same endpoint returns different response shapes, fields are merged intelligently:

First response:

{ "id": 1, "name": "Alice" }

Second response:

{ "id": 2, "name": "Bob", "avatar": "https://..." }

Merged schema:

interface Response {
  id: number;
  name: string;
  avatar?: string;  // Optional, appeared later
}

Output Structure

.api-alchemy/
├── schemas/
│   ├── get-users-id.json
│   └── get-repos-owner-repo.json
├── generated/
│   ├── get-users-id.ts
│   └── get-repos-owner-repo.ts
└── observations.json

TypeScript Integration

Generated types are fully TypeScript-compatible:

import type { GetUsersIdResponse } from './.api-alchemy/generated/get-users-id';

const response = await fetch('https://api.github.com/users/torvalds');
const user: GetUsersIdResponse = await response.json();

// Full type safety
console.log(user.login);     // ✓ OK
console.log(user.notexists); // ✗ TypeScript error

Performance

  • Non-blocking: Schema inference happens asynchronously via setImmediate
  • Minimal overhead: Negligible performance impact on requests
  • Batched writes: File operations are debounced

Edge Cases Handled

  • Empty responses
  • Non-JSON responses (skipped)
  • Circular object detection
  • Type unions (conflicting schemas)
  • Optional fields (inferred from frequency)
  • Large response bodies

Development vs Production

api-alchemy is designed for development only:

if (process.env.NODE_ENV === 'development') {
  global.fetch = instrumentFetch(fetch);
}

Or use a conditional import:

if (process.env.NODE_ENV === 'development') {
  const { instrumentFetch } = await import('api-alchemy');
  global.fetch = instrumentFetch(fetch);
}

Testing

Run tests with:

npm test

Tests cover:

  • Schema inference from various JSON structures
  • Schema merging and type union detection
  • Endpoint normalization (IDs, UUIDs, hashes)
  • TypeScript code generation
  • Type naming conventions

Future Features

  • [ ] Zod schema generation
  • [ ] OpenAPI/Swagger output
  • [ ] Axios interceptor
  • [ ] GraphQL schema inference
  • [ ] CLI for schema generation
  • [ ] IDE integration / Intellisense
  • [ ] Schema versioning
  • [ ] Traffic replay

License

ISC

Contributing

Contributions welcome! Please open an issue or PR on GitHub.