Skip to content

feat: support external emulator plugins#67

Open
jsj wants to merge 2 commits intovercel-labs:mainfrom
jsj:jsj/plugins
Open

feat: support external emulator plugins#67
jsj wants to merge 2 commits intovercel-labs:mainfrom
jsj:jsj/plugins

Conversation

@jsj
Copy link
Copy Markdown

@jsj jsj commented Apr 10, 2026

Summary

Adds a small external-plugin loading path on top of the existing ServicePlugin architecture.

This keeps built-in emulators unchanged, but lets teams run emulator packages that are not ready or appropriate for core yet:

npx emulate start --plugin ./plugins/my-service.ts --service my-service
npx emulate init --plugin ./plugins/my-service.ts --service my-service
npx emulate list --plugin ./plugins/my-service.ts

Programmatic usage also works:

await createEmulator({
  service: "my-service",
  plugins: ["./plugins/my-service.ts"],
});

Why this matters

The volume of emulator PRs since this was opened is the signal: service coverage is valuable, but every new provider currently has to land as a core registry/package change. That makes the project carry every niche, experimental, or company-specific emulator forever.

This PR gives maintainers a lower-risk answer:

  • widely useful emulators can still be built in;
  • experimental or private emulators can live outside this repo;
  • users still get the same start, init, list, seed config, auth fallback, and programmatic APIs.

Low-risk shape

  • Built-in service behavior is preserved.
  • Existing ServicePlugin is reused; no new runtime abstraction.
  • External plugins are opt-in via --plugin / plugins.
  • External plugin names cannot collide with built-ins.
  • Duplicate external plugin names are rejected.
  • Local paths and package names are both supported.
  • init all includes external plugins only when explicitly supplied.

Plugin contract

A plugin module exports a ServicePlugin as either plugin or default export.

Optional exports:

  • seedFromConfig
  • label
  • endpoints
  • defaultFallback
  • initConfig

The tests include a tiny echo-plugin.ts fixture to make the contract concrete and reviewable.

Test plan

  • pnpm --filter emulate type-check
  • pnpm --filter emulate test
  • pnpm --filter emulate lint

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Apr 10, 2026

@jsj is attempting to deploy a commit to the Vercel Labs Team on Vercel.

A member of the Team first needs to authorize it.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0d21292529

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/emulate/src/commands/init.ts Outdated
Comment thread packages/emulate/src/registry.ts Outdated
jsj added 2 commits April 30, 2026 17:17
emulate already uses a plugin-shaped internal architecture through per-service packages and ServicePlugin, but new emulators still require hardcoded core registry changes. This change reuses that existing service-entry path to allow external plugins while preserving built-in behavior and keeping scope limited to loading, listing, init, and programmatic startup.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant