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

pactwork

v1.2.1

Published

Contract-first API simulation framework - Mocks you can trust

Readme


Why Pactwork

The problem: API mocks drift from reality. You write them manually, the API evolves, and suddenly your tests pass but production breaks.

The fix: Point Pactwork at your OpenAPI spec. It generates MSW mocks, validates them continuously, and tells you the moment they fall out of sync.

| Without Pactwork | With Pactwork | |------------------|---------------| | Write mocks by hand | Generate from your spec | | Hope they match the API | Validate automatically | | Miss error states | Test every response your API can return | | Debug in production | Catch drift in development |

# One command. Mocks that match your API.
npx pactwork generate --spec ./openapi.yaml

Key Features

| Feature | What you get | |---------|-------------| | Mock Generation | Generate MSW mock handlers from any OpenAPI 2.0, 3.0, or 3.1 spec | | Drift Detection | Know immediately when your mocks fall out of sync with the spec | | Scenario Catalog | Test every error your API can return (404, 500, timeouts, etc.) | | Runtime Utilities | Simulate latency, flaky networks, and error sequences in tests | | Storybook Addon | Switch API states directly from the Storybook toolbar | | Coverage Reporting | See which API scenarios your Storybook stories cover | | CI Gates | Block deployments when mocks don't match the spec | | Type Generation | Get TypeScript types from your spec, always up to date |


Quick Start

Install

npm install -D pactwork msw

Generate mocks

# Generate MSW mock handlers from your OpenAPI spec
npx pactwork generate --spec ./openapi.yaml --output ./src/mocks

# Include error scenarios for testing
npx pactwork generate --spec ./openapi.yaml --with-scenarios

What you get

Pactwork generates ready-to-use MSW handlers and a scenario catalog:

src/mocks/
├── handlers.ts      # MSW handlers for every endpoint in your spec
└── scenarios.ts     # Error/edge case responses (404, 500, etc.)
// handlers.ts (generated)
import { http, HttpResponse } from 'msw'

export const handlers = [
  http.get('/api/users/:id', () => {
    return HttpResponse.json({ id: 1, name: 'Jane Doe', email: '[email protected]' })
  }),
  http.post('/api/users', () => {
    return HttpResponse.json({ id: 2, name: 'New User' }, { status: 201 })
  }),
  // ... one handler per operation in your spec
]

Use with MSW

Browser (Storybook, development):

import { setupWorker } from 'msw/browser'
import { handlers } from './mocks/handlers'

const worker = setupWorker(...handlers)
await worker.start()

Node (tests):

import { setupServer } from 'msw/node'
import { handlers } from './mocks/handlers'

const server = setupServer(...handlers)
beforeAll(() => server.listen())
afterAll(() => server.close())

Storybook Integration

Test every API state visually with @pactwork/storybook-addon.

Install

npm install -D @pactwork/storybook-addon

Configure

Register the addon in your Storybook config:

// .storybook/main.ts
export default {
  addons: ['@pactwork/storybook-addon'],
}

Then set up toolbar controls in your preview. See the full Storybook setup guide for the complete configuration.

What it does

| Control | Purpose | |---------|---------| | Scenario dropdown | Switch between success, error, and edge case responses | | Latency selector | Simulate slow networks (0ms to 5s) | | Network toggle | Simulate offline and connection errors | | Addon panel | See request logs, active state, and available mock handlers |

Set scenarios per story

// UserCard.stories.tsx
import { setScenario, resetState, setLatency } from '../mocks/handlers'

export const Loading: Story = {
  beforeEach: () => {
    resetState()
    setLatency(3000)
  },
}

export const NotFound: Story = {
  beforeEach: () => {
    resetState()
    setScenario('getUser', 'notFound')
  },
}

export const ServerError: Story = {
  beforeEach: () => {
    resetState()
    setScenario('getUser', 'serverError')
  },
}

Runtime Utilities

Control API behavior programmatically in your tests.

import { handlers, handlerMeta, scenarios } from './mocks'
import { applyScenario, withLatency, withSequence, pipe } from 'pactwork/runtime'

// Return a 404 for getUser
const errorHandlers = applyScenario(handlers, handlerMeta, 'getUser', scenarios.getUser.notFound)

// Slow down all responses by 500ms
const slowHandlers = withLatency(handlers, handlerMeta, 500)

// Simulate a flaky API: fail twice, then succeed
const flakyHandlers = withSequence(handlers, handlerMeta, 'getUser', [500, 500, 200])

// Compose multiple behaviors
const testHandlers = pipe(
  handlers,
  h => withLatency(h, handlerMeta, 100),
  h => applyScenario(h, handlerMeta, 'getUser', scenarios.getUser.notFound)
)

Available utilities

| Utility | What it does | |---------|-------------| | applyScenario(handlers, meta, operationId, scenario) | Replace a response with an error or edge case | | withLatency(handlers, meta, ms) | Add delay to all responses | | withLatency(handlers, meta, operationId, ms) | Add delay to one operation | | withSequence(handlers, meta, operationId, statuses) | Return different statuses in sequence | | withRateLimit(handlers, meta, operationId, opts) | Simulate rate limiting (429) | | withNetworkError(handlers, meta, operationId, opts) | Simulate timeout, abort, or connection errors | | withSeed(handlers, meta, seed) | Deterministic response data | | pipe(handlers, ...transformers) | Compose multiple utilities together |


CLI Commands

| Command | What it does | |---------|-------------| | pactwork generate | Generate MSW mock handlers from your spec | | pactwork validate | Check if mocks match the spec | | pactwork breaking | Compare two spec versions for breaking changes | | pactwork types | Generate TypeScript types from your spec | | pactwork scenarios | List available error scenarios from your spec | | pactwork coverage | Report which scenarios your Storybook stories cover | | pactwork can-i-deploy | CI gate — block deploys when mocks drift | | pactwork record | Create a contract from your spec | | pactwork verify | Verify a contract against the current spec |

Common flags

# CI mode — minimal output, strict exit codes
pactwork validate --ci

# Auto-fix — regenerate when drift is found
pactwork validate --fix

# Generate with error scenarios
pactwork generate --with-scenarios

# Compare API versions for breaking changes
pactwork breaking --old v1.yaml --new v2.yaml

# GitHub Actions annotations
pactwork validate --format github

# Coverage with minimum threshold
pactwork coverage --min-coverage 80

CI Integration

GitHub Action

- uses: adrozdenko/pactwork@v1
  with:
    spec: ./openapi.yaml

CLI in CI

steps:
  - name: Validate mocks
    run: npx pactwork validate --ci --format github

  - name: Check deployment safety
    run: npx pactwork can-i-deploy

Exit codes

| Code | Meaning | |------|---------| | 0 | Mocks match the spec | | 1 | Drift or breaking changes detected | | 2 | Warnings treated as errors |


Automated Drift Repair

For CI pipelines and AI agents, use this workflow to auto-fix drift:

# 1. Check for drift
pactwork validate --ci
# Exit 0 = mocks match, done
# Exit 1 = drift detected, continue

# 2. Regenerate mocks
pactwork generate

# 3. Verify the fix
pactwork validate --ci

# 4. Commit
git add src/mocks
git commit -m "fix: regenerate mocks from updated spec"

Configuration

Create pactwork.config.ts for project-wide settings:

import { defineConfig } from 'pactwork'

export default defineConfig({
  spec: { path: './api/openapi.yaml' },
  generate: {
    output: './src/mocks',
    typescript: true,
  },
})

Requirements

  • Node.js 20.11+
  • MSW 2.x
  • OpenAPI 2.0, 3.0, or 3.1 spec

Contributing

git clone https://github.com/adrozdenko/pactwork.git
npm install
npm test

See CONTRIBUTING.md for details.


License

MIT © adrozdenko