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-tape

v1.0.0

Published

Record real API responses as test fixtures. Auto-generate types, MSW handlers, and detect API drift.

Readme

apitape

npm version downloads CI license node zero deps

Snapshot your API. Auto-generate types, mocks, and drift detection — zero runtime dependencies.

Why apitape?

  • One command to capture a live API response, generate TypeScript types, and create MSW handlers
  • Drift detection compares fixtures against the live API — catch breaking changes in CI before your tests do
  • Zero dependencies — ships as a single package with no transitive installs
  • Programmatic API — every function is exported for library usage

Install

npm install api-tape

Quick Start

# 1. Initialize project
npx apitape init

# 2. Capture a live API response
npx apitape capture https://api.example.com/users --name users

# 3. Generate TypeScript types + MSW handler
npx apitape types --format typescript
npx apitape capture https://api.example.com/users --name users --typescript --msw

# 4. Detect drift in CI
npx apitape diff --fail-on-drift

Commands

| Command | Description | |---------|-------------| | init | Create fixtures/ directory and apitape.config.json | | capture <url> | Capture an API response as a JSON fixture | | types | Generate TypeScript or JSDoc types from all fixtures | | diff | Compare fixtures against live API to detect drift | | sync | Re-capture all fixtures from their original URLs | | import <spec> | Generate fixtures from an OpenAPI spec (JSON/YAML) | | mock <name> | Generate randomised data variants from a fixture | | export | Bundle all MSW handlers into a single file | | watch | Watch fixtures and auto-re-capture on metadata changes | | list | List all fixtures with metadata | | delete <name> | Remove a fixture and all generated files |

Run apitape <command> --help for full options.

Capture

# Auto-name from URL
apitape capture https://api.example.com/users

# Explicit name + auth + types + MSW in one shot
apitape capture https://api.example.com/users \
  --name users \
  --auth bearer --auth-token "$TOKEN" \
  --typescript --msw \
  --tag auth --tag v2

# POST with body (JSON string or @file)
apitape capture https://api.example.com/users \
  --name create-user --method POST \
  --data '{"name": "John"}'

# Capture error responses
apitape capture https://api.example.com/missing --name not-found --allow-error

# GraphQL query (auto-wraps as { query: ... }, forces POST)
apitape capture https://api.example.com/graphql --graphql -d '{ users { id name } }'

Watch

apitape watch                         # Poll every 3s, re-capture on metadata change
apitape watch --interval 5000         # Custom poll interval (ms)
apitape watch --typescript --msw      # Regenerate artifacts on capture

Drift Detection

apitape diff                          # Compare all fixtures
apitape diff --fail-on-drift --json   # CI mode: exit 1 on drift, JSON output
apitape diff --name users             # Single fixture
apitape diff --tag auth               # Tagged fixtures only
apitape diff --concurrency 8          # Parallel requests (default: 4)

Sync

apitape sync                    # Re-capture all from original URLs
apitape sync --dry-run          # Preview without changes
apitape sync --backup           # Backup before overwriting
apitape sync --concurrency 8    # Parallel requests (default: 4)

Mock Data

apitape mock users --count 5                    # 5 random variants
apitape mock users --count 3 --vary name email  # Vary specific fields
apitape mock users --seed 42                    # Deterministic output
apitape mock --all --typescript --msw           # All fixtures + artifacts

OpenAPI Import

apitape import ./openapi.yaml --mock --typescript --msw

Tagging

# Tag on capture
apitape capture https://api.example.com/login --name login --tag auth

# Filter any command by tag
apitape list --tag auth
apitape diff --tag auth
apitape sync --tag auth
apitape export --tag auth

Type Generation

Nested objects produce named interfaces:

export interface UsersAddress {
  street: string;
  city: string;
}

export interface Users {
  id: number;
  name: string;
  address: UsersAddress;
}

Configuration

apitape.config.json:

{
  "fixturesDir": "./fixtures",
  "typesOutput": "./fixtures",
  "typesFormat": "jsdoc",
  "environments": {
    "staging": { "baseUrl": "https://staging.api.example.com" },
    "production": { "baseUrl": "https://api.example.com" }
  },
  "auth": { "type": "bearer", "token": "your-default-token" },
  "defaultHeaders": { "Content-Type": "application/json" },
  "maxSizeBytes": 5242880,
  "arraySampleSize": 100
}

Environment resolution: apitape capture /users --env staging resolves to https://staging.api.example.com/users.

Auth in config is used automatically. CLI flags (--auth, --auth-token) override when provided.

CI Integration

# GitHub Actions
- name: Check API drift
  run: npx apitape diff --fail-on-drift --json

Programmatic API

All core functions are exported:

import {
  // Config
  loadConfig, resolveEnv, saveConfig, clearConfigCache,
  // HTTP
  fetchWithAuth,
  // Fixtures
  saveFixture, loadFixture, loadMetadata,
  listFixtures, deleteFixture, fixtureExists,
  // Types
  generateJSDoc, generateTypeScript, generateType, inferType, setArraySampleSize,
  // Diff
  diffObjects, formatDiffResult, hashValue, setDiffArraySampleSize,
  // Mock
  generateMockData, generateVariants, createRng,
  // MSW
  generateMSW, generateMSWHandlers,
  // Artifacts
  generateArtifacts, regenerateExistingArtifacts,
  // Errors
  ApitapeError, FixtureNotFoundError, ConfigError, FixtureSizeError, HttpRequestError,
  // Utils
  sanitizeName, toPascalCase, pAll
} from 'api-tape';
const response = await fetchWithAuth('https://api.example.com/users', {
  auth: { type: 'bearer', token: 'your-token' }
});

await saveFixture('users', response.data, {
  url: 'https://api.example.com/users',
  method: 'GET',
  tags: ['auth']
});

await generateArtifacts('users', response.data,
  { typescript: true, msw: true },
  { url: 'https://api.example.com/users', method: 'GET' }
);

// Drift detection
const fixture = await loadFixture('users');
const live = await fetchWithAuth('https://api.example.com/users');
const diff = diffObjects(fixture, live.data);
if (diff.status === 'breaking') console.error(formatDiffResult(diff));

// Mock variants
const variants = generateVariants(response.data, { count: 5, variations: ['name', 'email'] });

Limitations

  • Array drift detection samples a configurable number of items (default: 5). Items beyond the sample are not compared.
  • Mock generation is non-deterministic by default. Use --seed for reproducible output.
  • OpenAPI import supports JSON and YAML specs.

Requirements

Node.js ≥ 18.0.0 | Bun ≥ 1.0 | Deno ≥ 2.0

Contributing

git clone https://github.com/nbnd-z/apitape.git
cd apitape
npm install
npm test

License

MIT