Marvia

Sign inSign up

Topology

Dependencies point inward

The kernel depends on interfaces. Concrete providers are injected exactly once, at the composition root.

            apps/web (TanStack Start)
                     |
              @marvia/core  (ports + registries + loader)
                     |
   +---------+-------+--------+-----------+-----------+
   |         |                |           |           |
 database   auth           storage      queue       events
 (Drizzle) (Better Auth)  (R2 + KV)  (CF Queues)   (bus)
   |                                     |
 Postgres                          workers/* consumers
LayerMay importMust never import
apps/*@marvia/core, @marvia/ui, @marvia/sdkvendor SDKs
packages/coreadapter contractsany vendor SDK
adapter packages@marvia/shared@marvia/core
extensions/*@marvia/sdkanything else in the kernel

Boot sequence

How a Marvia runtime comes up

Five deterministic steps. Nothing self-registers by import side effect except the component registry.

  1. 1Parse environment through @marvia/config.
  2. 2Construct adapters: database driver, auth, storage, queue, cache.
  3. 3createKernel(ports) builds registries, the connector registry and the loader.
  4. 4Installed extensions load per workspace with their granted permissions.
  5. 5Routes, navigation, cards, reports and actions are read from the registries.

Snapshot engine

JSON is the record, never HTML

Architecture only — the kernel defines the pipeline stages, the fetcher and the extractor contract. It does not crawl.

URLfetchextractnormalizepersistemitreport

The snapshot body is written to object storage; only metadata reaches Postgres. Completion publishes snapshot.completed, which the report engine consumes to produce a document in the universal report schema.

Workers

Cloudflare Worker consumers

Each worker is a thin consumer. Adapters and pipelines are supplied by the host deployment, never hardcoded.

snapshot-worker

Drives fetch → extract → normalize → persist → emit.

connector-worker

Runs ConnectorAdapter.sync for queued integrations.

queue-worker

Single binding dispatching to registered consumers.

ai-worker

Executes queued AI tasks through the router.

cron-worker

Declarative scheduled task registry.

webhook-worker

Verifies signatures before any side effect.

Tenancy

Isolation is structural

Every repository method takes a WorkspaceId. Storage and cache keys are workspace-prefixed. Roles live on membership rows, never on the user record — privilege escalation is impossible by shape.