Architecture
Fusion is a polyrepo: every capability is an independently versioned package in its own repo, and a product app composes the ones it needs. This keeps each package small, separately testable, and replaceable.
The product apps follow the same split. The four project apps' logic — ProcessN,
ProtokollN, NyhetN, WikiN — lives in one package,
@tikab-interactive/pulsn-apps (one subpath per app); their UI
lives in fusion-ui; and the example app is a thin consumer that wires the two together
(transport, i18n, routing). Because the package is logic-only — every function takes an injected
{ db, reindex } context, never a singleton — it is fully testable on its own against an ephemeral
Postgres. (Flatbox and ChattN/Carola are separate.)
Dependency tiers
Packages are built and published bottom-up — a package can only be extracted once everything it depends on is published.
- Leaves (no internal deps):
fusion-db,fusion-env,fusion-ui,fusion-storage,fusion-ai,fusion-cache,fusion-ldap,fusion-gis,fusion-jobs,fusion-metrics,fusion-realtime,fusion-collab,fusion-edge-sso,fusion-import-export— extracted in any order. - Tier 2 (one internal dep):
fusion-mailer,fusion-audit,fusion-settings,fusion-search→fusion-db. - Auth:
fusion-auth→fusion-dbonly (see Conventions). For enterprise sign-in it ships an optional edge-SSO plugin (the/edge-ssoexport) that the app composes withfusion-edge-sso(trusted-header resolver) andfusion-ldap(directory sync) — see Enterprise SSO.
(The diagram above shows a representative slice — the full leaf set is larger; see the table below and Packages.)
The packages
| Package | What it does |
|---|---|
fusion-db | the createDb client factory + the reusable foundation schema (users, sessions, accounts, mailbox/audit/config/api-token); the app composes it with its own domains |
fusion-env | typed, validated environment variables (createAppEnv) |
fusion-auth | email/password auth (Better Auth) + API tokens + session helpers + an optional edge-SSO plugin (trusted-header sign-in) |
fusion-config | the shared TypeScript / Oxlint / Oxfmt configs + the reusable CI workflow |
fusion-storage | server-side object storage — MinIO / S3 locally, Azure Blob in the cloud |
fusion-ui | ready-to-use Mantine components — auth (login/logout), app shell, AI prompt/response, common elements; documented in Storybook |
fusion-ai | provider-pluggable LLM adapter — local Ollama or hosted OpenRouter, chosen from env; returns nothing when unconfigured so the app degrades gracefully (AI) |
others (fusion-cache, fusion-mailer, fusion-audit, fusion-settings, fusion-search, fusion-jobs, fusion-metrics, fusion-realtime, fusion-collab, fusion-gis, fusion-ldap, fusion-edge-sso, fusion-import-export) | caching, email, audit log, runtime settings, universal search (FTS + trigram + vector, RRF-fused), background jobs (Hatchet — also the agent scheduler), Prometheus metrics, realtime (Centrifugo), collaborative editing (Yjs), GIS (MapLibre/PostGIS), LDAP, edge SSO, CSV import/export — see Packages |
fusion-config is special: it's tooling shared by every other package, not a
runtime dependency.
Authorization lives in a sibling @tikab-interactive/typescript-rules package
(not fusion--scoped): a DB-agnostic permission engine — composable predicates in
named registries, plus a Drizzle adapter for row-level list filters. The example
builds its whole permission model on it — see Authorization.
How packages depend on each other
Internal dependencies are normal semver ranges resolved from GitHub Packages
("@tikab-interactive/fusion-db": "^2.0.0"), and each package versions
independently (fusion-db is past 2.0, fusion-ai is still 0.1). A change low in
the tree ripples up: bump fusion-db → bump its dependents → bump the app. Until a
package is published, an app can link it directly — see
Getting started.
For a full breakdown of the tier-1 leaf packages — runtime environment, external infra requirements, and sandbox demos — see Packages.