Schmock
March 21, 2026 · View on GitHub
Mock APIs from OpenAPI specs or hand-crafted routes. Callable API, plugin pipeline, framework adapters.
import { schmock } from '@schmock/core'
import { openapi } from '@schmock/openapi'
const mock = schmock({ state: {} })
mock.pipe(await openapi({
spec: './petstore.yaml',
seed: { pets: { count: 5 } }
}))
const res = await mock.handle('GET', '/pets')
// → { status: 200, body: [{ petId: 1, name: "Rex", ... }, ...] }
Why Schmock?
- OpenAPI-first: Point at a spec, get a fully functional CRUD mock with stateful collections, seed data, security validation, and content negotiation
- Callable API: No HTTP server needed — call
mock.handle()directly in tests - Plugin pipeline: Chain plugins with
.pipe()for validation, pagination, filtering, or custom logic - Framework adapters: Drop into Express middleware or Angular HTTP interceptor
- Smart data generation: Field-name-aware faker generates realistic data from schemas
Packages
| Package | Description |
|---|---|
@schmock/core | Core mock builder, routing, and plugin pipeline |
@schmock/openapi | Auto-register routes from OpenAPI/Swagger specs |
@schmock/faker | Faker-powered automatic data generation |
@schmock/validation | Request/response validation via AJV |
@schmock/query | Pagination, sorting, and filtering |
@schmock/express | Express middleware adapter |
@schmock/angular | Angular HTTP interceptor adapter |
@schmock/cli | Standalone CLI mock server |
Quick Start
npm install @schmock/core
Define routes, call them directly
const mock = schmock()
mock('GET /users', [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
])
mock('GET /users/:id', ({ params }) => {
const users = [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }]
return users.find(u => u.id === Number(params.id)) || [404, { error: 'Not found' }]
})
const res = await mock.handle('GET', '/users/1')
// → { status: 200, body: { id: 1, name: 'Alice' }, headers: {...} }
Stateful mocks with CRUD
const mock = schmock({ state: { items: [] } })
mock('POST /items', ({ body, state }) => {
const item = { id: state.items.length + 1, ...body }
state.items.push(item)
return [201, item]
})
mock('GET /items', ({ state }) => state.items)
await mock.handle('POST', '/items', { body: { name: 'Widget' } })
const list = await mock.handle('GET', '/items')
// list.body → [{ id: 1, name: 'Widget' }]
Mock from an OpenAPI spec
import { openapi } from '@schmock/openapi'
const mock = schmock({ state: {} })
mock.pipe(await openapi({
spec: './petstore.yaml',
seed: { pets: [{ petId: 1, name: 'Rex', tag: 'dog' }] },
security: true,
}))
await mock.handle('GET', '/pets') // list
await mock.handle('GET', '/pets/1') // get by id
await mock.handle('POST', '/pets', { // create
body: { name: 'Buddy', tag: 'dog' },
headers: { authorization: 'Bearer token' },
})
await mock.handle('DELETE', '/pets/1') // delete
Request spying
await mock.handle('POST', '/items', { body: { name: 'A' } })
await mock.handle('POST', '/items', { body: { name: 'B' } })
mock.called('POST', '/items') // true
mock.callCount('POST', '/items') // 2
mock.lastRequest('POST', '/items') // { body: { name: 'B' }, ... }
Plugin pipeline
import { validationPlugin } from '@schmock/validation'
import { queryPlugin } from '@schmock/query'
mock('GET /users', ({ state }) => state.users)
.pipe(validationPlugin({ request: { query: querySchema } }))
.pipe(queryPlugin({
pagination: { defaultLimit: 20 },
sorting: { allowed: ['name', 'created_at'] },
filtering: { allowed: ['role'] },
}))
// GET /users?filter[role]=admin&sort=name&page=2&limit=10
Framework adapters
Express:
import { toExpress } from '@schmock/express'
app.use('/api', toExpress(mock))
Angular:
import { provideSchmockInterceptor } from '@schmock/angular'
providers: [provideSchmockInterceptor(mock, { baseUrl: '/api' })]
CLI server
npm install -g @schmock/cli
schmock petstore.yaml --port 8080 --cors --seed seed.json
Documentation
| Guide | Description |
|---|---|
| Getting Started | Installation, core concepts, first mock |
| OpenAPI | Auto-mocking, CRUD, seed data, Prefer header, security, schema patching |
| Testing | Unit tests, integration tests, Angular & Express testing patterns |
| Express Adapter | Express middleware setup and options |
| Angular Adapter | Angular interceptor, helpers, TestBed setup |
| CLI | Command-line mock server |
| Plugin Development | Writing custom plugins |
| API Reference | Complete type and method reference |
| Debug Mode | Request lifecycle logging |
Contributing
See CONTRIBUTING.md for development setup and workflow.
License
MIT