Programmatic API
Use @pleaseai/emulate as a library — createEmulator, reset, and close for test suites.
Besides the CLI, @pleaseai/emulate exports a programmatic API for embedding
emulators directly in a test suite.
createEmulator
Section titled “createEmulator”import { createEmulator } from '@pleaseai/emulate'
const emulator = await createEmulator({ service: 'supabase', port: 4004, seed: { supabase: { anon_key: 'test-anon-key', tables: { todos: [{ id: 1, title: 'Buy groceries', completed: false }] }, }, },})
// emulator.url → "http://localhost:4004"// ... run your tests
emulator.reset() // restore seeded stateawait emulator.close() // shut down the HTTP serverOptions
Section titled “Options”| Option | Type | Description |
|---|---|---|
service | ServiceName | Which emulator to start ('kakao', 'supabase', …) — one per instance |
port | number | Port to listen on (default 4000) |
seed | SeedConfig | Same shape as emulate.config.yaml — a per-service section plus optional tokens |
baseUrl | string | Override the advertised base URL (useful behind a proxy) |
Instance methods
Section titled “Instance methods”| Member | Description |
|---|---|
url | Base URL the emulator is reachable at |
reset() | Clears the in-memory store and re-applies the seed — call between tests |
close() | Stops the HTTP server; resolves when the port is released |
Test-runner setup (bun:test / Vitest / Jest)
Section titled “Test-runner setup (bun:test / Vitest / Jest)”Start the emulator once per file (or in a global setup), reset between tests:
import { afterAll, beforeAll, beforeEach } from 'bun:test'import { createEmulator, type Emulator } from '@pleaseai/emulate'
let emulator: Emulator
beforeAll(async () => { emulator = await createEmulator({ service: 'kakao', port: 4000 })})
beforeEach(() => emulator.reset())
afterAll(() => emulator.close())reset() is synchronous and cheap (in-memory only), so per-test resets add
no meaningful overhead.
Testing routes without a port
Section titled “Testing routes without a port”Service plugins can also be exercised entirely in-process through
app.fetch, with no port bound at all — this is how the emulators’ own test
suites run:
import { createServer } from '@emulators/core'import { kakaoPlugin } from '@pleaseai/emulate-kakao'
const { app, store } = createServer(kakaoPlugin, { port: 4000 })kakaoPlugin.seed?.(store, 'http://localhost:4000')
const res = await app.fetch(new Request('http://localhost:4000/v2/user/me'))