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 emulate
import { 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

OptionDefaultDescription
service(required)Service name: 'vercel', 'github', 'google', 'slack', 'apple', 'microsoft', 'okta', 'aws', 'resend', 'stripe', 'mongoatlas', 'clerk', or 'linear'
port4000Port for the HTTP server
seednoneInline seed data (same shape as YAML config)
baseUrlnoneOverride 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

MethodDescription
urlBase 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/linear

Available packages

PackageService
@emulators/vercelVercel API
@emulators/githubGitHub API
@emulators/googleGoogle OAuth, Gmail, Calendar, Drive
@emulators/slackSlack Web API, OAuth v2, webhooks
@emulators/linearLinear GraphQL API, OAuth, webhooks
@emulators/appleApple Sign In / OIDC
@emulators/microsoftMicrosoft Entra ID, Graph API
@emulators/awsAWS S3, SQS, IAM, STS
@emulators/oktaOkta identity provider / OIDC
@emulators/mongoatlasMongoDB Atlas Admin API + Data API
@emulators/resendResend email API
@emulators/stripeStripe billing and payments API
@emulators/clerkClerk Backend API and OAuth
@emulators/coreShared store, middleware, and utilities
@emulators/adapter-nextNext.js App Router integration
@emulators/adapter-nuxtNuxt 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.