reason-machines/trending-skills1 file

Vercel Labs Emulate

Local drop-in API emulation for Vercel, GitHub, and Google services in CI and no-network sandboxes

Specification
Skill ID
reason-machines/trending-skills/vercel-labs-emulate
Publisher
reason-machines
Repository
trending-skills
Installs
0
Files
1
Synced
Sep 23, 2026
How to use it

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 emulate

CLI 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 list

Default 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

OptionDefaultDescription
service(required)'github', 'vercel', or 'google'
port4000Port for the HTTP server
seednoneInline seed data object (same shape as YAML config)

Instance Methods

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

Inline 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/github
Without oauth_apps configured, the emulator accepts any client_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: all

Sign 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/vercel

Real-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 }),
  ])

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.

Use this skill