
Vercel Labs Emulate
- 884 installs
- 66 repo stars
- Updated July 9, 2026
- aradotso/trending-skills
vercel-labs-emulate is a Claude Code skill for running production-fidelity local HTTP servers that replace Vercel, GitHub, and Google APIs for developers who need offline CI and sandbox tests without network calls.
About
vercel-labs-emulate wraps the vercel-labs/emulate project as a Daily 2026 Skills entry from aradotso/trending-skills. emulate spins up fully stateful, production-fidelity local HTTP servers as drop-in replacements for Vercel, GitHub, and Google APIs—designed for CI pipelines, Vitest suites, and no-network sandboxes rather than shallow mocks. Developers reach for vercel-labs-emulate when integration tests must exercise OAuth flows, deployment APIs, or GitHub endpoints without external dependencies. Triggers include emulating Vercel locally, mocking GitHub for tests, and running Google OAuth emulation in restricted environments. The skill guides agents to stand up compatible local servers so test code keeps production URL shapes while staying hermetic.
- Stateful in-memory servers with real pagination, OAuth, webhooks and cascading deletes
- Drop-in replacement for Vercel, GitHub, and Google APIs
- Works in CI pipelines and no-network sandboxes
- CLI commands: emulate, init, list, seed with YAML config
- Supports --service vercel,github and custom ports
Vercel Labs Emulate by the numbers
- 884 all-time installs (skills.sh)
- +6 installs in the week ending Jul 28, 2026 (Skillselion tracking)
- Ranked #552 of 2,184 Testing & QA skills by installs in the Skillselion catalog
- Security screen: HIGH risk (skills.sh audit)
- Data as of Jul 28, 2026 (Skillselion catalog sync)
npx skills add https://github.com/aradotso/trending-skills --skill vercel-labs-emulateAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 884 |
|---|---|
| repo stars | ★ 66 |
| Security audit | 2 / 3 scanners passed |
| Last updated | July 9, 2026 |
| Repository | aradotso/trending-skills ↗ |
How do you test Vercel APIs offline in CI?
Run production-fidelity local servers that emulate Vercel, GitHub, and Google APIs during tests and CI without needing network access.
Who is it for?
Developers writing Vitest or CI integration tests that call Vercel, GitHub, or Google APIs in no-network sandboxes.
Skip if: Production deployments or teams that only need simple fetch stubs without stateful API fidelity.
When should I use this skill?
Tests require Vercel, GitHub, or Google API calls and the environment blocks network or needs deterministic local endpoints.
What you get
Stateful local HTTP servers emulating Vercel, GitHub, and Google API endpoints for hermetic tests
- Local emulate server instances
- Hermetic integration test configuration
By the numbers
- Emulates three API providers: Vercel, GitHub, and Google
Files
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 }),
])
// Point your app's env vars at local emulators
process.env.GITHUB_API_URL = github.url
process.env.VERCEL_API_URL = vercel.url
process.env.GOOGLE_API_URL = google.url
})
afterEach(() => {
github.reset()
vercel.reset()
google.reset()
})
afterAll(() => Promise.all([github.close(), vercel.close(), google.close()]))CI Configuration
GitHub Actions
# .github/workflows/test.yml
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- name: Run tests with emulated APIs
run: npm test
env:
# Emulators start in vitest.setup.ts — no extra service needed
NODE_ENV: testDocker / No-Network Sandbox
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
# Tests start emulators programmatically — no outbound network needed
RUN npm testKey API Endpoints Reference
GitHub Emulator
GET /user # authenticated user
GET /repos/:owner/:repo # get repo
POST /user/repos # create repo
POST /repos/:owner/:repo/issues # create issue
PATCH /repos/:owner/:repo/issues/:number # update issue
POST /repos/:owner/:repo/pulls # create PR
PUT /repos/:owner/:repo/pulls/:number/merge # merge PR
GET /search/repositories # search repos
GET /search/issues # search issuesVercel Emulator
GET /v2/user # authenticated user
GET /v2/teams # list teams
POST /v11/projects # create project
GET /v10/projects # list projects
POST /v13/deployments # create deployment (auto → READY)
GET /v13/deployments/:idOrUrl # get deployment
POST /v10/projects/:id/env # create env vars
GET /v10/projects/:id/env # list env varsTroubleshooting
Port already in use
# Use a different base port
npx emulate --port 5000
# Or set via env
EMULATE_PORT=5000 npx emulateTests interfering with each other
// Always call reset() in afterEach, not afterAll
afterEach(() => emulator.reset())OAuth strict validation rejecting requests
- If you configure
oauth_appsorintegrations, only matchingclient_idvalues are accepted - Remove the
oauth_appsblock to fall back to accept-any mode
Emulator not receiving requests from app code
// Make sure your app reads the URL from env at request time, not module load time
// ✅ Good
async function fetchUser() {
return fetch(`${process.env.GITHUB_API_URL}/user`)
}
// ❌ Bad — captured before emulator starts
const API_URL = process.env.GITHUB_API_URLGitHub App JWT auth failing
- JWT must have
{ iss: "<app_id>" }as a string or number matching the configuredapp_id - Must be signed RS256 with the exact private key from config
- The emulator verifies the signature — use a real RSA key pair in tests
Related skills
How it compares
Pick vercel-labs-emulate over generic HTTP mocks when tests need stateful, production-shaped Vercel, GitHub, or Google endpoints in offline CI.
FAQ
Which APIs does vercel-labs-emulate cover?
vercel-labs-emulate guides use of vercel-labs/emulate to run local HTTP servers replacing Vercel, GitHub, and Google APIs. Servers are stateful and production-fidelity for CI and no-network sandboxes rather than minimal stub responses.
When should vercel-labs-emulate be used?
vercel-labs-emulate fits Vitest or CI jobs that must call Vercel, GitHub, or Google endpoints without network access. Use it for drop-in local API replacement, OAuth emulation, and integration tests in restricted environments.
Is Vercel Labs Emulate safe to install?
skills.sh reports 2 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.