Engine + Product Pattern
Migration history
- RFC-001 (2026-04-16) —
apps/andplatform/removed; modulesunified under area-first directories.
- 2026-04-26 —
platform/→engine/across all Areas; pairsunified under consumer module;
workspace/→suite/.- RFC-002 (2026-04-28) — The word "engine" in this pattern describes
a role (B2B white-label), not a directory name. B2B products always use a brand name as their directory (e.g.,
orbit/,nimbus/). The consumer product's server-side component isbackend/(notengine/).- RFC-003 / 006 / 007 (2026-04-28..29) — Full taxonomy: Domain (L1),
Area (L2), Sector (L3), distribution form (L4). Pairs share a Sector inside
products/<area>/<sector>/; the B2B brand variant lives at L4<brand>/. The L2 Areasuite/was renamed tohorizontal/.Paths below reflect the post-migration target state. The on-disk paths until each sweep completes still reflect the prior structure — see
taxonomy.md §10.
Every multi-tenant Koder SaaS ships as two named products: a B2B white-label engine and a B2C flagship consumer product running on top of it. The two always get different names, and they share the same Sector in the monorepo.
Why
- Opposite audiences. The engine is sold B2B to technical buyers — CTOs, founders, procurement. The product is sold B2C to end users — learners, listeners, patients, investors. Marketing, pricing, channel, and tone are fundamentally different. Forcing one name blurs both narratives.
- White-label clients do not want to compete with you. If a customer licenses Koder's engine to launch their own product, they are paying to own the user relationship. Sharing the engine's name with Koder's own flagship feels like paying to reinforce a rival brand.
- Operational disambiguation. When an incident happens, "Talk is down" is immediately unambiguous. "Koda is down" could mean the backend, the app, or the database — five extra minutes wasted during every outage.
- Precedent from the market. The pattern is well established and customers already understand it:
| Engine (B2B) | Flagship product (B2C) |
|---|---|
| Shopify | Shop (consumer app) |
| Stripe | Link |
| Twilio | Zoom (historical) |
| Mapbox | Google Maps |
| Auth0 | Okta (consumer-facing brand) |
The Koder pair registry
How pairs are organized in the monorepo
Both halves of a pair live inside the same Sector. The consumer product owns the Sector's L4 surfaces (backend/, app/{mobile,desktop,
web}/, landing/); the B2B engine lives as the L4 brand variant <brand>/ and contains its own backend/, landing/, and any enterprise-specific surfaces.
Example layout for Kmail / Raven:
products/horizontal/kmail/
├── backend/ ← Kmail B2C backend
├── app/
│ ├── mobile/ ← Kmail mobile
│ ├── desktop/ ← Kmail desktop
│ └── web/ ← Kmail webmail
├── raven/ ← Raven B2B brand variant
│ ├── backend/ ← Raven enterprise backend
│ └── landing/ ← raven.koder.dev
└── landing/ ← kmail.koder.devEstablished pairs (consistent — do not change)
| Sector (consumer) | B2B brand (L4 <brand>/) |
Domain |
|---|---|---|
products/horizontal/pulse/ |
orbit/ |
Social network |
products/horizontal/play/ |
media/ |
Video / music streaming |
products/horizontal/poly/ |
verba/ |
Language learning |
products/horizontal/beats/ |
cadence/ |
Music platform |
products/horizontal/lingo/ |
idiom/ |
Translation platform |
products/horizontal/kmail/ |
raven/ |
Email — engine + flagship webmail |
products/horizontal/learn/ |
academia/ |
E-learning / LMS |
products/horizontal/kampus/ |
campus/ |
Campus management |
products/vertical/clinic/ |
health/ |
Healthcare (EHR, openEHR, telemedicine) |
products/vertical/home/ |
ion/ |
IoT / smart home |
products/vertical/invest/ |
exchange/ |
Fintech trading |
products/vertical/helo/ |
rova/ |
Service marketplace |
products/dev/sky/ |
nimbus/ |
Multi-cloud management (AWSGCPAzureOracleOVH/Hetzner) |
products/dev/store/ |
depot/ |
App distribution |
services/foundation/kompass/ |
(consumer app: Mosaic at app/mobile/, app/desktop/) |
Universal organization management |
Open-core service pairs (engine + SaaS)
Some pairs are shaped differently: the engine ships as open-core (engine/ at L4 inside an engines/ Sector), and a managed SaaS exists as a sibling deployment with its own backend/ and landing/.
| Engine Sector (open-core) | SaaS deployment | Domain |
|---|---|---|
infra/observe/wire/ |
hosted at wire.koder.dev (managed) |
Network diagnostics |
infra/observe/apm/ |
hosted at apm.koder.dev (managed) |
APM / tracing |
infra/observe/log/ |
hosted at log.koder.dev (managed) |
Log aggregation |
Pending splits
None. All engine + product pairs in the Koder Stack now use distinct names.
Non-pair solo products (no split needed)
Single-tenant products or internal tools that do not need a separate B2B engine:
| Sector | Reason |
|---|---|
products/dev/flow/ |
Git forge, one name |
infra/data/kdb/ |
Database infrastructure, one name |
services/ai/kortex/ |
DevOps AI brain, one name |
services/ai/kode/ |
Consumer AI client (Kode), one name |
products/dev/kterm/ |
Terminal, one name |
engines/lang/koda/ |
Language compiler/runtime |
products/horizontal/crew/ |
HCM / workforce management, B2B only |
These do not need engine + product splits because they are either (a) infrastructure that is not white-labeled, or (b) single-name consumer tools that do not have an enterprise engine angle.
Naming conventions for new multi-tenant products
When you create a new multi-tenant SaaS, pick two names from day one. Do not defer the second name — it is much harder to split later.
Engine name guidelines
The engine is the infrastructure brand. It is read by technical buyers, sales engineers, and docs. It should feel:
- Institutional — latin or greek roots work well (verba, orbit, ion, lingua)
- Specific to the substance — kdb says "database", jet says "fast web server"
- Short — four to six letters is ideal
- Unique in the Koder family — grep the monorepo before choosing
- Unlikely to collide with market brands — search
"Name" site:github.comand"Name" SaaSbefore committing
Avoid:
- Real English words that have other technical meanings (mesh already is
infra/net/mesh, vault already isservices/crypto/vault) - Names that sound like famous products (mongo, aurora, sonic)
- Names that are hard to pronounce in Portuguese, English, and Spanish simultaneously
Product name guidelines
The product is the consumer brand. It is read by end users who may never hear the engine name. It should feel:
- Emotional — evoke the benefit, not the mechanism
- Short — three to six letters is ideal (poly, talk, home, pulse)
- Memorable out loud — passes the "I tell a friend at the bar" test
- Distinct sonically from sibling products — avoid homophones (koda