Sub-documents
| Document |
Topic |
| engine.md |
Resolution engine — Resolvable, Resolver, DecofileProvider, resolve pipeline |
| blocks.md |
Block system — all block types, adapt/decorate, manifest registration |
| runtime.md |
Runtime request flow — Hono, middleware chain, routes, rendering |
| hooks-components.md |
Hooks, components, and client-side code |
| plugins-clients.md |
Fresh plugins, client-side invoke proxy, formdata utils |
| site-usage.md |
How a Deco site uses the framework — a production VTEX site as reference |
| deco-vs-blocks.md |
Mapping deco-cx/deco (Fresh) → @decocms/start (TanStack) |
deco-cx/deco Core Architecture
Reference for the deco-cx/deco repository — the core Deco framework powering Fresh/Deno storefronts.
Repository Overview
deco/
├── mod.ts # Main entry — re-exports engine, runtime, blocks, context
├── mod.web.ts # Web/client entry — invoke proxy, stream reader
├── deco.ts # DecoContext, RequestContext, AsyncLocalStorage bindings
├── live.ts # Re-export of deco.ts (legacy alias)
├── types.ts # DecoManifest, DecoState, block type constants
├── deps.ts # External deps (OpenTelemetry, std, durable, inspect)
├── deno.json # v1.177.5 — imports, exports, tasks
│
├── engine/ # Resolution engine (45 files)
│ ├── core/ # Resolver, Resolvable, resolve pipeline
│ ├── manifest/ # Manifest builder, generation, defaults
│ ├── decofile/ # State providers (filesystem, JSON, realtime)
│ ├── schema/ # JSON Schema generation and introspection
│ └── importmap/ # Import map builder for blocks
│
├── blocks/ # Block definitions (15 files)
│ ├── section.ts # UI components with optional loader/action
│ ├── loader.ts # Data fetching blocks (cached, single-flight)
│ ├── action.ts # Mutation blocks
│ ├── handler.ts # HTTP request handlers
│ ├── flag.ts # Feature flags
│ ├── matcher.ts # Audience targeting predicates
│ ├── page.tsx # Page-level sections
│ ├── app.ts # App containers with manifest + state
│ ├── workflow.ts # Durable workflows
│ └── function.ts # Legacy loader format
│
├── runtime/ # Request handling (51 files)
│ ├── mod.ts # Deco class — main runtime entry
│ ├── handler.tsx # Hono app setup, route registration
│ ├── middleware.ts # Middleware chain (liveness, state, o11y, response)
│ ├── routes/ # Built-in routes (/live/invoke, /deco/render, etc.)
│ ├── features/ # Invoke, render, meta, preview, styles
│ ├── fresh/ # Fresh framework plugin + Bindings
│ ├── htmx/ # HTMX framework (alternative renderer)
│ ├── fetch/ # Instrumented fetch (logging, caching)
│ └── caches/ # LRU, Redis, tiered, filesystem caches
│
├── hooks/ # Server-side hooks (6 files)
├── components/ # Framework components (5 files)
├── plugins/ # Fresh plugins (3 files)
├── clients/ # Client-side invoke proxy (3 files)
├── commons/ # JWT, workflows
├── utils/ # HTTP, cookies, timings, invoke helpers
├── observability/ # OpenTelemetry instrumentation
├── daemon/ # Sidecar/embedded daemon for dev
├── dev/ # Dev server utilities
├── hypervisor/ # Multi-site orchestration
└── scripts/ # Release, dev, bundle scripts
Core Concepts
1. Everything is a Resolvable
The fundamental unit in Deco is a Resolvable — an object with a __resolveType field pointing to a resolver:
// A resolvable stored in the decofile (CMS state)
{
"__resolveType": "site/loaders/productList.ts",
"query": "shoes",
"count": 12
}
The engine recursively resolves all props, then invokes the matching resolver function.
2. Blocks define the type system
Each block type (section, loader, action, etc.) defines how modules are adapted into resolvers:
- section → wraps a Preact component, adding SSR + optional data loading
- loader → wraps a function with caching, single-flight dedup, and tracing
- action → wraps a mutation function with tracing
- handler → produces an HTTP handler from config
- matcher → evaluates a predicate against request context
- flag → combines matchers with variants for feature flags
- app → bundles manifest + state + dependencies
3. DecofileProvider manages state
The decofile is the CMS state — a Record<string, Resolvable>. Providers can be:
- Filesystem (
newFsProvider) — reads from local .json/.jsonl files
- Realtime — connects to CMS websocket for live updates
- JSON — static in-memory state
4. Request flow
Request → Hono
→ bindings middleware (RENDER_FN, GLOBALS)
→ liveness probe (/deco/_liveness)
→ state builder (prepareState, debug, echo)
→ observability (OpenTelemetry trace/span)
→ main middleware (CORS, headers, cache, segment)
→ route matching:
/styles.css → tailwind CSS
/live/_meta → schema + manifest
/live/invoke/* → single/batch invoke
/deco/render → partial section render
* (catch-all) → page handler → resolve → render
5. Two rendering frameworks
| Framework |
Islands |
Partials |
Usage |
| Fresh |
Preact islands |
<Partial> + f-partial |
Standard Deco sites |
| HTMX |
None (no JS) |
hx-get/hx-swap |
Lightweight alternative |
6. Invoke system
Client-side code calls server loaders/actions via the invoke API:
// Client-side (runtime.ts in a site)
import { proxy } from "@deco/deco/web";
const invoke = proxy<Manifest>();
// Calls POST /live/invoke/site/loaders/productList.ts
const products = await invoke["site/loaders/productList.ts"]({ query: "shoes" });
Key Exports
mod.ts (main)
Context — AsyncLocalStorage-based context
$live, initContext, newContext — engine initialization
Deco, PageData — runtime class and page data type
Block, BlockFunc, Resolvable, Resolved — type system
asResolved, isDeferred, isResolvable — resolution utilities
allowCorsFor — CORS utility
JsonViewer, Framework — components
mod.web.ts (client)
proxy, withManifest, forApp — invoke proxy builders
readFromStream — SSE stream reader
InvokeAwaiter — chainable invoke proxy
deco.ts (context)
DecoContext — site, siteId, deploymentId, platform, release, runtime
RequestContext — signal, framework
Context.active() — current context
Context.bind(ctx, fn) — run fn with context
Dependencies
- Runtime: Deno, Fresh 1.6.8, Preact 10.23.1
- Observability: OpenTelemetry (api, sdk-trace, sdk-metrics, sdk-logs)
- Framework: Hono (HTTP router)
- Deco ecosystem:
@deco/durable, @deco/inspect-vscode, @deco/warp
- Std:
@std/assert, @std/async, @std/crypto, @std/encoding, @std/http
- Compiler:
jsx: "react-jsx", jsxImportSource: "preact"
1---2name: deco-core-architecture3description: Architecture reference for deco-cx/deco — the core Deco framework for Fresh/Deno. Covers the resolution engine (Resolvable → Resolver pipeline), block system (sections, loaders, actions, flags, matchers, handlers, apps, workflows), runtime request flow (Hono + Fresh/HTMX), DecofileProvider (state management), manifest generation, plugin system, hooks (useSection, useScript, useDevice), client-side invoke proxy, and the relationship between deco-cx/deco (Fresh/Deno) and @decocms/start (TanStack/Node). Use when exploring the deco repo, understanding how the framework works, building new block types, debugging resolution issues, or porting deco internals to TanStack Start.4---56## Sub-documents78| Document | Topic |9|----------|-------|10| [engine.md](./engine.md) | Resolution engine — Resolvable, Resolver, DecofileProvider, resolve pipeline |11| [blocks.md](./blocks.md) | Block system — all block types, adapt/decorate, manifest registration |12| [runtime.md](./runtime.md) | Runtime request flow — Hono, middleware chain, routes, rendering |13| [hooks-components.md](./hooks-components.md) | Hooks, components, and client-side code |14| [plugins-clients.md](./plugins-clients.md) | Fresh plugins, client-side invoke proxy, formdata utils |15| [site-usage.md](./site-usage.md) | How a Deco site uses the framework — a production VTEX site as reference |16| [deco-vs-blocks.md](./deco-vs-blocks.md) | Mapping deco-cx/deco (Fresh) → @decocms/start (TanStack) |1718# deco-cx/deco Core Architecture1920Reference for the `deco-cx/deco` repository — the core Deco framework powering Fresh/Deno storefronts.2122## Repository Overview2324```25deco/26├── mod.ts # Main entry — re-exports engine, runtime, blocks, context27├── mod.web.ts # Web/client entry — invoke proxy, stream reader28├── deco.ts # DecoContext, RequestContext, AsyncLocalStorage bindings29├── live.ts # Re-export of deco.ts (legacy alias)30├── types.ts # DecoManifest, DecoState, block type constants31├── deps.ts # External deps (OpenTelemetry, std, durable, inspect)32├── deno.json # v1.177.5 — imports, exports, tasks33│34├── engine/ # Resolution engine (45 files)35│ ├── core/ # Resolver, Resolvable, resolve pipeline36│ ├── manifest/ # Manifest builder, generation, defaults37│ ├── decofile/ # State providers (filesystem, JSON, realtime)38│ ├── schema/ # JSON Schema generation and introspection39│ └── importmap/ # Import map builder for blocks40│41├── blocks/ # Block definitions (15 files)42│ ├── section.ts # UI components with optional loader/action43│ ├── loader.ts # Data fetching blocks (cached, single-flight)44│ ├── action.ts # Mutation blocks45│ ├── handler.ts # HTTP request handlers46│ ├── flag.ts # Feature flags47│ ├── matcher.ts # Audience targeting predicates48│ ├── page.tsx # Page-level sections49│ ├── app.ts # App containers with manifest + state50│ ├── workflow.ts # Durable workflows51│ └── function.ts # Legacy loader format52│53├── runtime/ # Request handling (51 files)54│ ├── mod.ts # Deco class — main runtime entry55│ ├── handler.tsx # Hono app setup, route registration56│ ├── middleware.ts # Middleware chain (liveness, state, o11y, response)57│ ├── routes/ # Built-in routes (/live/invoke, /deco/render, etc.)58│ ├── features/ # Invoke, render, meta, preview, styles59│ ├── fresh/ # Fresh framework plugin + Bindings60│ ├── htmx/ # HTMX framework (alternative renderer)61│ ├── fetch/ # Instrumented fetch (logging, caching)62│ └── caches/ # LRU, Redis, tiered, filesystem caches63│64├── hooks/ # Server-side hooks (6 files)65├── components/ # Framework components (5 files)66├── plugins/ # Fresh plugins (3 files)67├── clients/ # Client-side invoke proxy (3 files)68├── commons/ # JWT, workflows69├── utils/ # HTTP, cookies, timings, invoke helpers70├── observability/ # OpenTelemetry instrumentation71├── daemon/ # Sidecar/embedded daemon for dev72├── dev/ # Dev server utilities73├── hypervisor/ # Multi-site orchestration74└── scripts/ # Release, dev, bundle scripts75```7677## Core Concepts7879### 1. Everything is a Resolvable8081The fundamental unit in Deco is a **Resolvable** — an object with a `__resolveType` field pointing to a resolver:8283```typescript84// A resolvable stored in the decofile (CMS state)85{86 "__resolveType": "site/loaders/productList.ts",87 "query": "shoes",88 "count": 1289}90```9192The engine recursively resolves all props, then invokes the matching resolver function.9394### 2. Blocks define the type system9596Each block type (section, loader, action, etc.) defines how modules are adapted into resolvers:9798- **section** → wraps a Preact component, adding SSR + optional data loading99- **loader** → wraps a function with caching, single-flight dedup, and tracing100- **action** → wraps a mutation function with tracing101- **handler** → produces an HTTP handler from config102- **matcher** → evaluates a predicate against request context103- **flag** → combines matchers with variants for feature flags104- **app** → bundles manifest + state + dependencies105106### 3. DecofileProvider manages state107108The decofile is the CMS state — a `Record<string, Resolvable>`. Providers can be:109- **Filesystem** (`newFsProvider`) — reads from local `.json`/`.jsonl` files110- **Realtime** — connects to CMS websocket for live updates111- **JSON** — static in-memory state112113### 4. Request flow114115```116Request → Hono117 → bindings middleware (RENDER_FN, GLOBALS)118 → liveness probe (/deco/_liveness)119 → state builder (prepareState, debug, echo)120 → observability (OpenTelemetry trace/span)121 → main middleware (CORS, headers, cache, segment)122 → route matching:123 /styles.css → tailwind CSS124 /live/_meta → schema + manifest125 /live/invoke/* → single/batch invoke126 /deco/render → partial section render127 * (catch-all) → page handler → resolve → render128```129130### 5. Two rendering frameworks131132| Framework | Islands | Partials | Usage |133|-----------|---------|----------|-------|134| **Fresh** | Preact islands | `<Partial>` + `f-partial` | Standard Deco sites |135| **HTMX** | None (no JS) | `hx-get/hx-swap` | Lightweight alternative |136137### 6. Invoke system138139Client-side code calls server loaders/actions via the invoke API:140141```typescript142// Client-side (runtime.ts in a site)143import { proxy } from "@deco/deco/web";144const invoke = proxy<Manifest>();145146// Calls POST /live/invoke/site/loaders/productList.ts147const products = await invoke["site/loaders/productList.ts"]({ query: "shoes" });148```149150## Key Exports151152### `mod.ts` (main)153- `Context` — AsyncLocalStorage-based context154- `$live`, `initContext`, `newContext` — engine initialization155- `Deco`, `PageData` — runtime class and page data type156- `Block`, `BlockFunc`, `Resolvable`, `Resolved` — type system157- `asResolved`, `isDeferred`, `isResolvable` — resolution utilities158- `allowCorsFor` — CORS utility159- `JsonViewer`, `Framework` — components160161### `mod.web.ts` (client)162- `proxy`, `withManifest`, `forApp` — invoke proxy builders163- `readFromStream` — SSE stream reader164- `InvokeAwaiter` — chainable invoke proxy165166### `deco.ts` (context)167- `DecoContext` — site, siteId, deploymentId, platform, release, runtime168- `RequestContext` — signal, framework169- `Context.active()` — current context170- `Context.bind(ctx, fn)` — run fn with context171172## Dependencies173174- **Runtime**: Deno, Fresh 1.6.8, Preact 10.23.1175- **Observability**: OpenTelemetry (api, sdk-trace, sdk-metrics, sdk-logs)176- **Framework**: Hono (HTTP router)177- **Deco ecosystem**: `@deco/durable`, `@deco/inspect-vscode`, `@deco/warp`178- **Std**: `@std/assert`, `@std/async`, `@std/crypto`, `@std/encoding`, `@std/http`179- **Compiler**: `jsx: "react-jsx"`, `jsxImportSource: "preact"`