@x12i/api-playground
v0.4.4
Published
Catalog-driven API playground: endpoint nav, docs, try-it chrome, local runs history, env settings, static server, and dual-process launcher. Product apps supply catalogs and domain renderers.
Maintainers
Readme
@x12i/api-playground
Catalog-driven API playground shell for any HTTP service set.
Ships endpoint navigation, documentation view, Try-it chrome, local run history, environment settings, a zero-dependency static server, and a dual-process (API + UI) launcher. Your product supplies the endpoint catalog, request forms, and domain response renderers. This package stays HTTP-only — it never imports your service packages.
Used in-repo by the web-agentic playground (apps/playground → @x12i/web-agentic-api).
Install
pnpm add @x12i/api-playground
# or: npm i @x12i/api-playgroundRequires Node.js 20+. Plain ESM — no build step, no bundler required.
What you get
| Export | Role |
|---|---|
| @x12i/api-playground / create-playground.js | Shell factories: createCatalogNav, createDocsView, createEnv, createRuns, createResponseView, catalog helpers |
| server.mjs | createStaticServer({ root, port, apiOrigin, mounts }) |
| launch-dev-ui.mjs | launchDevUi({ root, apiPort, uiPort, apiStart, uiStart, … }) |
| assets/shell.css | Three-pane chrome styles (theme tokens) |
| assets/shell.html | Reference chrome markup |
Quick start (static server + mounts)
Serve your product UI and mount this package so the browser can import it without a bundler:
import { createRequire } from "node:module";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
import { createStaticServer } from "@x12i/api-playground/server.mjs";
const require = createRequire(import.meta.url);
const pkg = dirname(require.resolve("@x12i/api-playground/package.json"));
const root = dirname(fileURLToPath(import.meta.url));
createStaticServer({
root,
port: Number(process.env.PORT ?? 7081),
apiOrigin: process.env.API_ORIGIN ?? "http://localhost:7080",
logLabel: "my-playground",
mounts: [
{ urlPrefix: "/@api-playground/", fsRoot: join(pkg, "src") },
{ urlPrefix: "/@api-playground-assets/", fsRoot: join(pkg, "assets") },
],
});In index.html:
<link rel="stylesheet" href="/@api-playground-assets/shell.css" />
<script type="module" src="./app.js"></script>In the browser:
import {
createCatalogNav,
createDocsView,
createEnv,
createRuns,
createResponseView,
storageKey,
} from "/@api-playground/create-playground.js";Pass your catalog (groups + endpoints), a storagePrefix (e.g. "myapp"), and product hooks for submit / response rendering.
Dual-process launcher
import { launchDevUi } from "@x12i/api-playground/launch-dev-ui.mjs";
await launchDevUi({
root: process.cwd(),
apiPort: 7080,
uiPort: 7081,
healthPath: "/health",
apiStart: { command: "node", args: ["dist/api.js"], env: { PORT: "7080" } },
uiStart: ({ uiPort, apiOrigin }) => ({
command: "node",
args: ["playground/server.mjs"],
env: { PORT: String(uiPort), API_ORIGIN: apiOrigin },
}),
});Reuses a healthy API when /health already responds. Set NO_OPEN=1 to skip opening a browser.
Catalog contract
Each endpoint should include:
- Identity:
id,group,name,method,path,family - Docs:
summary,purpose,useWhen,internalFlow,inputs,responseDescription, … - UI:
requestUi,responseViews,submitLabel, optionalexamples
See src/types.js for the full typedef. Product apps own the endpoint list; this package only provides helpers (filterEndpoints, indexById, groupLabel, storageKey).
Product responsibilities
Keep in your app (not this package):
- Endpoint catalog data
- Try-it form markup and submit handlers
- Domain-specific response renderers (search tables, LLM briefs, …)
- Branding / storage prefix / default API origin
Docs
Product Docify (this monorepo): guide api-playground, Overview book §9, use case embed-api-playground.
Standalone knowledge pack (devDependency for agents):
pnpm add -D @x12i/api-playground-docs
npx api-playground-docs list-use-cases
npx api-playground-docs use-case embed-shellRebuild in this monorepo: pnpm docs:api-playground.
License
MIT
