CentraKit Turborepo app and package topology.
CentraKit is a Turborepo monorepo using pnpm workspaces. Internal packages use the @workspace/* alias.
| App | Framework | Purpose |
|---|---|---|
apps/saas | Next.js | Auth, dashboard, customer UI, organization UI, and admin UI. |
apps/api | Next.js | REST API and MCP server. |
apps/docs | Fumadocs on Next.js | Public documentation site generated from root docs/. |
apps/marketing | Next.js | Marketing website. |
apps/showcase | Next.js | Component and product UI showcase. |
apps/cli | Node.js | centrakit CLI. |
| Package | Purpose |
|---|---|
@workspace/foundation | List/API primitives, validation, env contracts, opaque ID helpers. |
@workspace/identity | Auth, users, and RBAC contracts. |
@workspace/tenant | Organizations, teams, and tags. |
@workspace/crm | Customers and collaboration contracts. |
@workspace/catalog | Products, inventory, customer assets, and files. |
@workspace/work | Tasks and agenda. |
@workspace/people | Employees, HR settings, schedules, time, time off, approvals, equipment, onboarding, hiring and people insights. |
@workspace/commerce | Quotes, invoices, orders, shipments, promotions, purchase orders, expenses, templates, and document primitives. |
@workspace/conversations | AI settings, chat, channels/inbox, agent runs, knowledge, and memory. |
@workspace/automation | Workflows and integrations. |
@workspace/platform | Billing/usage, audit log, notifications, analytics, settings, and the command center contract. |
@workspace/portal | Customer-portal aggregate read models. |
| Package | Purpose |
|---|---|
@workspace/core | Request context, auth, RBAC, and audit helpers (no all-services bag). |
@workspace/core-* | Domain-scoped request factories (core-tenant, core-crm, core-catalog, core-work, core-people, core-commerce, core-conversations, core-automation, core-platform, core-portal). |
@workspace/core-ai-runtime | Server runtime for assistant chat and specialist streams, AI approval gates, and the agent chat workflows. |
@workspace/core-workflow-runtime | Workflow graph dispatcher, scheduled runs, lifecycle nodes, and the commerce and order event reactors. |
@workspace/core-command-center | Command center record search and commands, composed from several core-* factories. |
@workspace/supabase-runtime | Clients, generated DB types, shared provider primitives. |
@workspace/supabase-* | Bounded Supabase implementations aligned to contract packages, including supabase-people. |
| Package | Purpose |
|---|---|
@workspace/ai | AI Gateway models, assistant tools, prompts, knowledge retrieval, memory, and AI suggestions. |
@workspace/inbox | Chat SDK channel adapters, inbound channel webhook processing, and the inbox agent tools. |
@workspace/email | Resend client, inbound email parsing, and the React Email templates. |
@workspace/stripe | Stripe client, billing and usage providers, invoice payments, and webhook verification. |
@workspace/seo | Brand defaults, metadata helpers, icons, and JSON-LD components. |
@workspace/product-pdf | Product page and product label PDFs with QR codes. |
@workspace/quote-pdf | Quote, invoice, and order document PDFs and their fonts. |
@workspace/business-registry | KVK and VIES business lookups, in packages/integrations/business-registry. |
@workspace/google-calendar | Read-only Google Calendar API client and schemas, in packages/integrations/google-calendar. |
packages/integrations/ is a folder of packages, not a package itself. pnpm-workspace.yaml lists it separately as packages/integrations/*.
| Package | Purpose |
|---|---|
@workspace/ui | Shared React components and Tailwind CSS 4 design tokens. |
@workspace/api-client | OpenAPI-generated typed API client. |
@workspace/next-config | Shared Next.js config factory. |
@workspace/typescript-config | Shared TypeScript configuration. |
Lint and format presets come from Ultracite 8 (ultracite/oxlint/* and ultracite/oxfmt). The root oxlint.config.ts and oxfmt.config.ts add the house rules. See ADR 0013.
apps/* -> @workspace/core, @workspace/core-*, bounded contracts, @workspace/ui, @workspace/api-client, shared config
apps/* -> never @workspace/supabase-* or another app
packages/core / core-* -> may import contracts and matching @workspace/supabase-*
packages/supabase-* -> may import their contracts + supabase-runtime only; never apps/core/other providers
contract packages -> zod/better-result and lower contracts only; never core or providerspnpm boundaries enforces these rules through the tags in each workspace turbo.json and the boundaries block in the root turbo.json:
| Tag | Packages | May depend on |
|---|---|---|
contract | The bounded contract packages, including people. | contract, config |
integration | email, stripe, seo, product-pdf, quote-pdf, api-client, business-registry, google-calendar | contract, config |
provider | supabase-runtime and every supabase-* package. | contract, config, provider |
core | core, every core-* package (including core-ai-runtime, core-workflow-runtime and core-command-center), ai and inbox. | core, contract, provider, integration, config |
ui | ui | config and @workspace/foundation |
app | Everything under apps/. | core, contract, provider, integration, ui, config and test |
The app tag allows provider because Turbo applies boundary rules to dependencies of dependencies: every app reaches @workspace/supabase-* through @workspace/core-*, so denying provider would fail every app. The appImportPatterns rule in the root oxlint.config.ts blocks a direct @workspace/supabase-* import from app code, and no app lists one in its dependencies (ADR 0002).
Contract packages expose explicit subpaths (./schemas, ./service, ./errors, domain roots). They do not expose a runtime . barrel that pulls Zod into client graphs.
Keep the contract graph acyclic. identity and tenant build on foundation. CRM depends on identity and tenant. Catalog and work depend on CRM and tenant. Commerce depends on CRM and work. Portal depends on catalog and commerce. People depends only on foundation. Conversations depends on identity and tenant. Automation depends on catalog, commerce, conversations and CRM. Platform depends on tenant and must not import conversations; orchestration joins those packages in core-*.
Use package-owned baseline:payload scripts, which the CI Build job runs after the build, to capture SaaS and CLI size artifacts. The bundle analyzer runs only on a manual workflow run. See CI And Release.
Last updated on