Labsco
vercel-labs logo

emulate

1,500

by vercel · part of vercel-labs/emulate

Local drop-in API emulator for Vercel, GitHub, Google, Slack, Apple, Microsoft, and AWS. Use when the user needs to start emulated services, configure seed…

🔥🔥🔥🔥✓ VerifiedFreeQuick setup
🧰 Not standalone. This skill ships with vercel-labs/emulate and only works together with that tool — install the tool first, then add this skill.

Local drop-in API emulator for Vercel, GitHub, Google, Slack, Apple, Microsoft, and AWS. Use when the user needs to start emulated services, configure seed…

Inspect the full instructions your agent will receiveExpand

This is the exact playbook injected into your agent when the skill activates — shown here so you can audit it before installing. You don't need to read it to use the skill.

by vercel

Local drop-in API emulator for Vercel, GitHub, Google, Slack, Apple, Microsoft, and AWS. Use when the user needs to start emulated services, configure seed… npx skills add https://github.com/vercel-labs/emulate --skill emulate Download ZIPGitHub1.5k

Service Emulation with emulate

Local drop-in replacement services for CI and no-network sandboxes. Fully stateful, production-fidelity API emulation, not mocks.

CLI

Copy & paste — that's it
# Start all services (zero-config)
npx emulate

# Start specific services
npx emulate --service vercel,github

# Custom base port (auto-increments per service)
npx emulate --port 3000

# Use a seed config file
npx emulate --seed config.yaml

# Generate a starter config
npx emulate init

# Generate config for a specific service
npx emulate init --service vercel

# List available services
npx emulate list

Options

Flag Default Description -p, --port 4000 Base port (auto-increments per service) -s, --service all Comma-separated services to enable --seed auto-detect Path to seed config (YAML or JSON) --base-url none Override advertised base URL (supports {service} template) --portless off Serve over HTTPS via portless (auto-registers aliases)

The port can also be set via EMULATE_PORT or PORT environment variables.

The advertised base URL (used in OAuth redirects, webhook URLs, etc.) can be overridden via --base-url, the EMULATE_BASE_URL env var (supports {service} template), or per-service baseUrl in the seed config. When running under portless, the PORTLESS_URL env var is also detected automatically.

Programmatic API

Copy & paste — that's it
npm install emulate

Each call to createEmulator starts a single service:

Copy & paste — that's it
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()

Options

Option Default Description service (required) 'vercel', 'github', 'google', 'slack', 'apple', 'microsoft', 'okta', 'aws', 'resend', 'stripe', 'mongoatlas', 'clerk', 'linear', or 'twilio' port 4000 Port for the HTTP server seed none Inline seed data (same shape as YAML config) baseUrl none Override advertised base URL. Per-service baseUrl in seed config takes highest priority, then this option, then EMULATE_BASE_URL env var (supports {service}), 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

HTTPS with portless

portless gives emulators trusted HTTPS URLs with auto-generated certs. Use the --portless flag to auto-register each service as a portless alias:

Copy & paste — that's it
npx emulate start --portless
# github https://github.emulate.localhost
# google https://google.emulate.localhost
# ...

This requires the portless proxy to be running (portless proxy start). If portless is not installed, emulate will prompt to install it.

The --portless flag overwrites any existing portless aliases matching *.emulate. Aliases are removed automatically when emulate shuts down.

For a single service behind portless:

Copy & paste — that's it
portless github.emulate emulate start --service github

For a custom base URL without portless (any reverse proxy):

Copy & paste — that's it
npx emulate start --base-url "https://{service}.myproxy.test"
# or
EMULATE_BASE_URL="https://{service}.myproxy.test" npx emulate start

The PORTLESS_URL env var is automatically set by the portless CLI wrapper when running a command through it (e.g. portless github.emulate emulate start), typically to a value like https://{service}.emulate.localhost. It supports {service} interpolation, just like --base-url and EMULATE_BASE_URL. When no explicit baseUrl is provided, it is used as a fallback.

Per-service overrides in the seed config (these take highest priority over all other base URL sources):

Copy & paste — that's it
github:
 baseUrl: https://github.emulate.localhost
google:
 baseUrl: https://google.emulate.localhost

Pointing Your App at the Emulator

Set environment variables to override real service URLs:

Copy & paste — that's it
VERCEL_EMULATOR_URL=http://localhost:4000
GITHUB_EMULATOR_URL=http://localhost:4001
GOOGLE_EMULATOR_URL=http://localhost:4002
SLACK_EMULATOR_URL=http://localhost:4003
APPLE_EMULATOR_URL=http://localhost:4004
MICROSOFT_EMULATOR_URL=http://localhost:4005
AWS_EMULATOR_URL=http://localhost:4007
LINEAR_EMULATOR_URL=http://localhost:4012

Then use these in your app to construct API and OAuth URLs. See each service's skill for SDK-specific override instructions.

Framework Integration (Embedded Mode)

The @emulators/adapter-next package embeds emulators directly into a Next.js app on the same origin. See the next skill (skills/next/SKILL.md) for full setup, Auth.js configuration, persistence, and font tracing details.

The @emulators/adapter-nuxt package embeds emulators directly into a Nuxt app on the same origin. See the nuxt skill (skills/nuxt/SKILL.md) for the server route, Nuxt config, OAuth configuration, and persistence setup.

Persistence

By default, all emulator state is in-memory. For persistence across process restarts and serverless cold starts, use a PersistenceAdapter.

Built-in file persistence

Copy & paste — that's it
import { filePersistence } from '@emulators/core'

// CLI or local dev: persists to a JSON file
const adapter = filePersistence('.emulate/state.json')

Custom adapters

Copy & paste — that's it
import type { PersistenceAdapter } from '@emulators/core'

const kvAdapter: PersistenceAdapter = {
 async load() { return await kv.get('emulate-state') },
 async save(data) { await kv.set('emulate-state', data) },
}

State is loaded on cold start and saved after every mutating request (POST, PUT, PATCH, DELETE). Saves are serialized to prevent race conditions.

Architecture

Copy & paste — that's it
packages/
 emulate/ # CLI entry point + programmatic API
 @emulators/
 core/ # HTTP server, Store, plugin interface, middleware
 adapter-next/ # Next.js App Router integration
 adapter-nuxt/ # Nuxt server route integration
 vercel/ # Vercel API service plugin
 github/ # GitHub API service plugin
 google/ # Google OAuth 2.0 / OIDC plugin
 slack/ # Slack Web API, OAuth, incoming webhooks plugin
 linear/ # Linear GraphQL API, OAuth, webhooks plugin
 twilio/ # Twilio Messaging, Verify, Voice, webhooks plugin
 apple/ # Sign in with Apple / OIDC plugin
 microsoft/ # Microsoft Entra ID OAuth 2.0 / OIDC plugin
 aws/ # AWS S3, SQS, IAM, STS plugin

The core provides a generic Store with typed Collection<T> instances supporting CRUD, indexing, filtering, and pagination. Each service plugin registers routes with the shared internal app and uses the store for state.