The framework and integration layer behind Deco CMS storefronts.
blocks is a Bun workspace monorepo containing Deco's framework-agnostic CMS runtime, Studio admin protocol, code generators, framework bindings, and portable commerce integrations. Packages are published together under the @decocms/* scope and export TypeScript source directly—there is no bundled dist layer or duplicated runtime state.
- Why blocks
- Architecture
- Packages
- Getting started
- Migration
- Development
- Contributing
- Contributors
- Documentation
- License
- One CMS runtime: resolve pages, sections, flags, matchers, loaders, and request-scoped state without tying the core to a web framework.
- Native framework bindings: render through TanStack Start on Cloudflare Workers, Next.js App Router/RSC, or generate native authoring artifacts for Eitri.
- Studio-ready: expose metadata, content snapshots, invokes, and live previews through the Deco admin protocol.
- Portable integrations: share commerce types and connect VTEX, Shopify, Magento, Salesforce Commerce Cloud, Algolia, Resend, blog, SEO, analytics, and theme capabilities.
- Migration tooling included: move Fresh/Preact storefronts to TanStack Start or upgrade older
@decocms/startsites to the split packages.
The dependency graph is intentionally one-way. Framework packages compose the lower layers; the runtime never imports a framework binding.
Storefront or native app
│
┌────────────────┼─────────────────┐
│ │ │
@decocms/tanstack @decocms/nextjs @decocms/eitri
│ │ │
├──────┬─────────┘ │
│ │ │
@decocms/blocks-admin @decocms/blocks-cli
│ │ │
└──────┴──────────┬────────────────┘
│
@decocms/blocks
▲
│
@decocms/apps-*
The split fixes the module-state duplication that occurred when the former @decocms/start package bundled multiple copies of shared singletons. Every public export now resolves to its owning package's source.
packages/
├── blocks/ CMS runtime and portable SDK
├── blocks-admin/ Studio protocol and admin setup
├── blocks-cli/ Code generation, audits, and migrations
├── tanstack/ TanStack Start + Cloudflare Workers binding
├── nextjs/ Next.js App Router binding
├── eitri/ Eitri schema and decofile generator
└── apps-*/ Shared capabilities and platform integrations
examples/
├── tanstack-smoke/ Minimal TanStack consumer
└── nextjs-smoke/ Minimal Next.js consumer
docs/ Architecture, operations, troubleshooting, and guides
.agents/skills/ Agent-assisted migration playbooks
All packages are versioned and released in lockstep.
| Package | Purpose |
|---|---|
@decocms/blocks |
Framework-agnostic CMS resolution, section registry, flags, matchers, middleware, hooks, and SDK utilities. |
@decocms/blocks-admin |
Studio protocol handlers for metadata, decofile content, invokes, previews, and admin setup. |
@decocms/blocks-cli |
Incremental code generation, validation, observability tooling, and storefront migration CLIs. |
| Package | Target | Highlights |
|---|---|---|
@decocms/tanstack |
TanStack Start + Cloudflare Workers | CMS routes, worker entry, Vite plugin, deferred sections, and KV-backed fast deploy. |
@decocms/nextjs |
Next.js 15+ App Router | RSC-native pages and previews, route handlers, root layout, and one-call setup. |
@decocms/eitri |
Eitri mobile stack | Generates self-contained Studio schema and decofile artifacts; rendering remains native. |
| Package | Integration |
|---|---|
@decocms/apps-commerce |
Shared commerce types, registry, SDK, and portable utilities. |
@decocms/apps-website |
SEO, analytics, themes, fonts, and generic website capabilities. |
@decocms/apps-vtex |
VTEX Commerce. |
@decocms/apps-shopify |
Shopify. |
@decocms/apps-magento |
Magento. |
@decocms/apps-salesforce |
Salesforce Commerce Cloud. |
@decocms/apps-algolia |
Algolia search. |
@decocms/apps-blog |
Blog content and CMS integration. |
@decocms/apps-resend |
Resend transactional email. |
The monorepo uses Bun 1.3+. The web bindings target React 19; Eitri is generation-only. Pick the binding that matches your application.
bun add @decocms/blocks @decocms/blocks-admin @decocms/tanstack \
@tanstack/react-start @tanstack/react-query @tanstack/store react react-dom
bun add -d viteBootstrap the runtime and Studio protocol in your server setup:
import { createAdminSetup } from "@decocms/blocks-admin/setup";
import { createSiteSetup } from "@decocms/blocks/setup";
import { setupTanstackFastDeploy } from "@decocms/tanstack";
createSiteSetup({
sections: import.meta.glob("./sections/**/*.tsx"),
blocks: {},
});
createAdminSetup({ meta: () => Promise.resolve({}), css: "" });
setupTanstackFastDeploy();Add decoVitePlugin() to Vite and mount cmsRouteConfig() in the catch-all route. See the working tanstack-smoke application and the fast deploy guide for production wiring.
bun add @decocms/blocks @decocms/blocks-admin @decocms/nextjsThe Next.js binding has four required integration points:
- wrap
next.configwithwithDeco(); - create an
ensureSetupfunction withcreateNextSetup(); - mount the Studio catch-all route and RSC preview page;
- await setup from the root layout and render CMS pages with
createDecoPage().
The complete copy-ready setup is in the @decocms/nextjs guide. A minimal end-to-end implementation lives in nextjs-smoke.
bun add -d @decocms/eitri
bunx deco-eitri init
bunx deco-eitri generateEitri uses Deco for schema and content authoring, then renders sections natively. See the @decocms/eitri guide.
Choose the migration path based on the site's current stack:
| From | To | Guide |
|---|---|---|
| Fresh / Preact / Deno | TanStack Start / React / Workers | deco-to-tanstack-migration |
| Automated Fresh migration | TanStack Start / React / Workers | deco-migrate-script |
@decocms/start@6.x + @decocms/apps@5.x |
Split v7 TanStack packages | decocms-v6-to-v7-upgrade |
@decocms/start@5.x Next tiers |
Split Next.js packages | deco-next-package-migration |
These playbooks follow the Agent Skills format and can be used from Codex, Claude Code, Cursor, or another compatible agent.
Install dependencies from the repository root:
bun installCommon commands:
| Command | What it checks |
|---|---|
bun run build |
Builds every package with TypeScript. |
bun run typecheck |
Type-checks every package without emitting files. |
bun run test |
Runs the Vitest suite for every package. |
bun run lint |
Runs Biome across package sources and scripts. |
bun run lint:unused |
Finds unused exports with Knip. |
bun run audit:secrets |
Scans package sources for leaked secrets. |
bun run check |
Runs typecheck, lint, unused-export checks, and the secrets audit. |
This repository contains libraries rather than a root application. Run either smoke app directly when you need a development server:
cd examples/tanstack-smoke && bun run dev
# or
cd examples/nextjs-smoke && bun run devTo test unpublished local changes in another site, run bun link inside each package you need, then link those package names from the consuming site.
Contributions are welcome. Before opening a pull request:
- read
CLAUDE.mdfor the package boundaries and load-bearing architectural constraints; - keep changes inside the package that owns the concern—especially the one-way dependency graph;
- add or update tests for behavior changes;
- run
bun run checkand the relevant package tests; - use Conventional Commits so semantic-release can determine the next version.
For migration-tooling work, the signed-off decisions in MIGRATION_TOOLING_PLAN.md are authoritative. For release history, see the changelog and GitHub releases.
Thanks to everyone who has helped build and improve Deco blocks.
New contributors are always welcome—start with an open issue or propose a focused pull request.
| Topic | Guide |
|---|---|
| Fast deploy and KV-backed content | docs/fast-deploy.md |
| Observability | docs/observability.md |
| Troubleshooting | docs/troubleshooting.md |
| Operations runbooks | docs/runbooks |
| Deco filesystem contract | docs/deco-fs-contract.md |
| Hydration and SSR migration | docs/hydration-and-ssr-migration.md |
| Known gaps | docs/known-gaps.md |
| Storefront implementation skills | docs/skills |
This repository does not currently declare a license. Contact the maintainers before redistributing or incorporating the source outside the terms under which you received it.