Vercel Labs Emulate
Local drop-in API emulation for Vercel, GitHub, and Google services in CI and no-network sandboxes
- Skill ID
- reason-machines/trending-skills/vercel-labs-emulate
- Publisher
- reason-machines
- Repository
- trending-skills
- Installs
- 0
- Files
- 1
- Synced
- Sep 23, 2026
Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.
reason-machines/trending-skills/vercel-labs-emulateInstalls these files- SKILL.md
What this skill tells the agent
vercel-labs/emulate
Skill by ara.so — Daily 2026 Skills collection.
emulate provides fully stateful, production-fidelity local HTTP servers that replace Vercel, GitHub, and Google APIs. Designed for CI pipelines and no-network sandboxes — not mocks, real in-memory state with proper pagination, OAuth, webhooks, and cascading deletes.
Installation
# CLI (no install needed)
npx emulate
# Or install as a dev dependency
npm install --save-dev emulateCLI Usage
# Start all services with defaults
npx emulate
# Start specific services
npx emulate --service vercel,github
# Custom base port (auto-increments per service)
npx emulate --port 3000
# Start with seed data
npx emulate --seed emulate.config.yaml
# Generate a starter config
npx emulate init
# Generate config for a specific service
npx emulate init --service github
# List available services
npx emulate listDefault ports:
- Vercel →
http://localhost:4000 - GitHub →
http://localhost:4001 - Google →
http://localhost:4002
Port can also be set via EMULATE_PORT or PORT environment variables.
Programmatic API
import { createEmulator, type Emulator } from 'emulate'
// Start a single service
const github = await createEmulator({ service: 'github', port: 4001 })
const vercel = await createEmulator({ service: 'vercel', port: 4002 })
console.log(github.url) // 'http://localhost:4001'
console.log(vercel.url) // 'http://localhost:4002'
// Reset state (replays seed data)
github.reset()
// Shutdown
await github.close()
await vercel.close()Options
| Option | Default | Description |
|---|---|---|
service | (required) | 'github', 'vercel', or 'google' |
port | 4000 | Port for the HTTP server |
seed | none | Inline seed data object (same shape as YAML config) |
Instance Methods
| Method | Description |
|---|---|
url | Base URL of the running server |
reset() | Wipe in-memory store and replay seed data |
close() | Shut down the server (returns Promise) |
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_URL = github.url
process.env.VERCEL_URL = vercel.url
})
afterEach(() => {
github.reset()
vercel.reset()
})
afterAll(() => Promise.all([github.close(), vercel.close()]))// vitest.config.ts
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
setupFiles: ['./vitest.setup.ts'],
environment: 'node',
},
})Seed Configuration
Create emulate.config.yaml in your project root (auto-detected):
# Auth tokens
tokens:
my_token:
login: admin
scopes: [repo, user]
vercel:
users:
- username: developer
name: Developer
email: dev@example.com
teams:
- slug: my-team
name: My Team
projects:
- name: my-app
team: my-team
framework: nextjs
github:
users:
- login: octocat
name: The Octocat
email: octocat@github.com
orgs:
- login: my-org
name: My Organization
repos:
- owner: octocat
name: hello-world
language: JavaScript
auto_init: true
google:
users:
- email: testuser@example.com
name: Test User
oauth_clients:
- client_id: my-client-id.apps.googleusercontent.com
client_secret: $GOOGLE_CLIENT_SECRET
redirect_uris:
- http://localhost:3000/api/auth/callback/googleInline Seed (Programmatic)
const github = await createEmulator({
service: 'github',
port: 4001,
seed: {
users: [
{ login: 'testuser', name: 'Test User', email: 'test@example.com' }
],
repos: [
{ owner: 'testuser', name: 'my-repo', language: 'TypeScript', auto_init: true }
],
},
})OAuth Configuration
GitHub OAuth Apps
github:
oauth_apps:
- client_id: $GITHUB_CLIENT_ID
client_secret: $GITHUB_CLIENT_SECRET
name: My Web App
redirect_uris:
- http://localhost:3000/api/auth/callback/githubWithoutoauth_appsconfigured, the emulator accepts anyclient_id(backward-compatible). With apps configured, strict validation is enforced.
GitHub Apps (JWT Auth)
github:
apps:
- app_id: 12345
slug: my-github-app
name: My GitHub App
private_key: |
-----BEGIN RSA PRIVATE KEY-----
...your PEM key...
-----END RSA PRIVATE KEY-----
permissions:
contents: read
issues: write
events: [push, pull_request]
installations:
- installation_id: 100
account: my-org
repository_selection: allSign JWTs with { iss: "<app_id>" } using RS256 — the emulator verifies the signature.
Vercel Integrations
vercel:
integrations:
- client_id: $VERCEL_CLIENT_ID
client_secret: $VERCEL_CLIENT_SECRET
name: My Vercel App
redirect_uris:
- http://localhost:3000/api/auth/callback/vercelReal-World Test Patterns
Testing a GitHub API Client
import { createEmulator } from 'emulate'
import { Octokit } from '@octokit/rest'
describe('GitHub integration', () => {
let emulator: Awaited<ReturnType<typeof createEmulator>>
let octokit: Octokit
beforeAll(async () => {
emulator = await createEmulator({
service: 'github',
port: 4001,
seed: {
users: [{ login: 'testuser', name: 'Test User' }],
repos: [{ owner: 'testuser', name: 'my-repo', auto_init: true }],
},
})
octokit = new Octokit({
baseUrl: emulator.url,
auth: 'any-token',
})
})
afterEach(() => emulator.reset())
afterAll(() => emulator.close())
it('creates and fetches an issue', async () => {
const { data: issue } = await octokit.issues.create({
owner: 'testuser',
repo: 'my-repo',
title: 'Test issue',
body: 'This is a test',
})
expect(issue.number).toBe(1)
expect(issue.state).toBe('open')
const { data: fetched } = await octokit.issues.get({
owner: 'testuser',
repo: 'my-repo',
issue_number: issue.number,
})
expect(fetched.title).toBe('Test issue')
})
})Testing a Vercel Deployment Workflow
import { createEmulator } from 'emulate'
describe('Vercel deployment', () => {
let emulator: Awaited<ReturnType<typeof createEmulator>>
beforeAll(async () => {
emulator = await createEmulator({
service: 'vercel',
port: 4002,
seed: {
users: [{ username: 'dev', email: 'dev@example.com' }],
projects: [{ name: 'my-app', framework: 'nextjs' }],
},
})
process.env.VERCEL_API_URL = emulator.url
})
afterEach(() => emulator.reset())
afterAll(() => emulator.close())
it('creates a deployment and transitions to READY', async () => {
const res = await fetch(`${emulator.url}/v13/deployments`, {
method: 'POST',
headers: {
Authorization: 'Bearer any-token',
'Content-Type': 'application/json',
},
body: JSON.stringify({ name: 'my-app', target: 'production' }),
})
const deployment = await res.json()
expect(deployment.readyState).toBe('READY')
})
})Testing Multiple Services Together
import { createEmulator, type Emulator } from 'emulate'
let github: Emulator
let vercel: Emulator
let google: Emulator
beforeAll(async () => {
;[github, vercel, google] = await Promise.all([
createEmulator({ service: 'github', port: 4001 }),
createEmulator({ service: 'vercel', port: 4002 }),
createEmulator({ service: 'google', port: 4003 }),
])
More from reason-machines
Use this skill in a project
Open any RiverX project, search the Skills panel for reason-machines/trending-skills/vercel-labs-emulate, and install it in one click.
