Programmatic API
Use emulators as libraries in your tests and scripts. There are two approaches: the emulate CLI package (which wraps all services) and the individual @emulators/* scoped packages.
CLI package
The emulate package provides a createEmulator helper that starts any service by name.
npm install emulateimport { createEmulator } from 'emulate'
const github = await createEmulator({ service: 'github', port: 4001 })
const vercel = await createEmulator({ service: 'vercel', port: 4002 })
github.url // 'http://localhost:4001'
vercel.url // 'http://localhost:4002'
await github.close()
await vercel.close()Vitest / Jest setup
// vitest.setup.ts
import { createEmulator, type Emulator } from 'emulate'
let github: Emulator
let vercel: Emulator
beforeAll(async () => {
;[github, vercel] = await Promise.all([
createEmulator({ service: 'github', port: 4001 }),
createEmulator({ service: 'vercel', port: 4002 }),
])
process.env.GITHUB_EMULATOR_URL = github.url
process.env.VERCEL_EMULATOR_URL = vercel.url
})
afterEach(() => { github.reset(); vercel.reset() })
afterAll(() => Promise.all([github.close(), vercel.close()]))createEmulator options
| Option | Default | Description |
|---|---|---|
service | (required) | Service name: 'vercel', 'github', 'google', 'slack', 'apple', 'microsoft', 'okta', 'aws', 'resend', 'stripe', 'mongoatlas', 'clerk', or 'linear' |
port | 4000 | Port for the HTTP server |
seed | none | Inline seed data (same shape as YAML config) |
baseUrl | none | Override the advertised base URL (used in OAuth redirects, webhook URLs, etc.). Per-service baseUrl in seed config takes highest priority, then this option, then the EMULATE_BASE_URL env var (supports {service} template), then PORTLESS_URL (supports {service}, automatically set by the portless CLI wrapper), then http://localhost:<port>. |
Instance methods
| Method | Description |
|---|---|
url | Base URL of the running server |
reset() | Wipe the store and replay seed data |
close() | Shut down the HTTP server, returns a Promise |
Scoped packages
Each emulator is published as its own @emulators/* package. Install only the ones you need:
npm install @emulators/github @emulators/google @emulators/linearAvailable packages
| Package | Service |
|---|---|
@emulators/vercel | Vercel API |
@emulators/github | GitHub API |
@emulators/google | Google OAuth, Gmail, Calendar, Drive |
@emulators/slack | Slack Web API, OAuth v2, webhooks |
@emulators/linear | Linear GraphQL API, OAuth, webhooks |
@emulators/apple | Apple Sign In / OIDC |
@emulators/microsoft | Microsoft Entra ID, Graph API |
@emulators/aws | AWS S3, SQS, IAM, STS |
@emulators/okta | Okta identity provider / OIDC |
@emulators/mongoatlas | MongoDB Atlas Admin API + Data API |
@emulators/resend | Resend email API |
@emulators/stripe | Stripe billing and payments API |
@emulators/clerk | Clerk Backend API and OAuth |
@emulators/core | Shared store, middleware, and utilities |
@emulators/adapter-next | Next.js App Router integration |
@emulators/adapter-nuxt | Nuxt server route integration |
Direct usage
Each scoped package exports its service plugin and seed helpers:
import * as github from '@emulators/github'
import * as stripe from '@emulators/stripe'These are the same modules used internally by the CLI and the Next.js adapter or Nuxt adapter. See the framework integration pages for full examples of using scoped packages with createEmulateHandler.