Skip to content
OpenPerf
Esc
↑↓navigate↵open⌘Jpreview
On this page

Project layout

Where code goes in the monorepo.

Path Holds
apps/ Services and web apps, such as api, web and mcp.
tools/ Developer CLIs that never deploy, such as the demo telemetry seeder.
packages/domain Vocabulary and models shared by the browser and the server.
packages/server Code shared by the server apps, one module per directory in src/.
packages/deft The design system: components, theme and tokens.
packages/sdk @openperf/sdk, published to npm.
apps/docs This site: product, self-hosting, Deft UI and development docs.
  • Code used by one app lives in that app. Move it to a package once a second app needs it.
  • Apps import a server module through its subpath, such as @openperf/server/ingest. Modules import each other only through the other module’s barrel, never its internals.
  • @openperf/deft publishes only its index.ts. A primitive the apps need goes to Deft with a Deft UI page and an example; a composite bound to app data stays in the app.
  • A change to a service, port, environment variable or deploy step updates its Self-hosting page in the same change.
  • @openperf/sdk is the only package built with vp pack. Its entry points are /node, /bun, /browser and /cli; src/core stays internal. OpenTelemetry versions are pinned in the root catalog.
  • Every third-party package bundled into the SDK dist is listed in deps.onlyBundle in packages/sdk/vite.config.ts, and its license is in packages/sdk/THIRD_PARTY_LICENSES.md, which ships to npm. The build fails on an unlisted package. After adding, removing or bumping an SDK dependency, run the /update-sdk-licenses Claude Code skill (.claude/skills/update-sdk-licenses); without Claude, build the SDK and run its generate.sh from the repository root.

Was this page helpful?