Skip to content

decocms/deco-start

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

533 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

@decocms/start

npm version license

Framework layer for deco.cx storefronts on TanStack Start + React 19 + Cloudflare Workers.

@decocms/start is the npm package that storefronts depend on. It provides the CMS bridge, admin protocol, section registry, schema generation, edge caching, the Vite plugin, and a small SDK. It is not itself a storefront β€” it is what storefronts build on top of.

πŸ“– Read the full documentation β†’


What's in the box

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Site repo (your storefront)                    β”‚  ← Components, sections, routes
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚   @decocms/apps  (commerce integrations)         β”‚  ← VTEX, Shopify, Resend
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚   @decocms/start  (framework β€” this package)     β”‚  ← CMS bridge, admin, caching
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
              ↓ runs on ↓
   TanStack Start  +  React 19  +  Cloudflare Workers

@decocms/start exports cover four surfaces:

  • Worker entry β€” createDecoWorkerEntry wraps your Cloudflare Worker with admin routes, edge cache, and asset bypass.
  • CMS bridge β€” loadCmsPage, resolveDecoPage, registerSectionLoaders, registerLayoutSections.
  • Admin protocol β€” handleMeta, handleDecofile, handleRender, handleInvoke.
  • SDK β€” createCachedLoader, createInstrumentedFetch, createInvoke, decoVitePlugin, plus utilities (cookies, redirects, sitemap, A/B testing).

Full export reference: docs.deco.cx/v2/en/reference/package-exports.


Hello, World

A minimal v2 storefront has six files. Here they are.

package.json

{
  "name": "my-store",
  "type": "module",
  "scripts": {
    "dev": "vite dev",
    "build": "vite build",
    "deploy": "wrangler deploy"
  },
  "dependencies": {
    "@decocms/start": "^2.28.0",
    "@decocms/apps": "^1.11.0",
    "@tanstack/react-start": "^1.166.0",
    "react": "^19.0.0",
    "react-dom": "^19.0.0"
  },
  "devDependencies": {
    "vite": "^6.0.0",
    "wrangler": "^4.72.0"
  }
}

vite.config.ts

import { defineConfig } from "vite";
import { cloudflare } from "@cloudflare/vite-plugin";
import { tanstackStart } from "@tanstack/react-start/plugin/vite";
import react from "@vitejs/plugin-react";
import decoVitePlugin from "@decocms/start/vite";

export default defineConfig({
  plugins: [
    cloudflare({ viteEnvironment: { name: "ssr" } }),
    tanstackStart({ server: { entry: "server" } }),
    react({ babel: { plugins: ["babel-plugin-react-compiler"] } }),
    decoVitePlugin(),
  ],
  resolve: {
    alias: { "~": "/src" },
    deduplicate: ["react", "react-dom", "@decocms/start", "@decocms/apps"],
  },
});

wrangler.jsonc

{
  "name": "my-store",
  "main": "./src/worker-entry.ts",
  "compatibility_date": "2026-02-14",
  "compatibility_flags": [
    "nodejs_compat",
    "no_handle_cross_request_promise_resolution"
  ],
  "assets": { "directory": "./dist/client" }
}

src/setup.ts

import { createSiteSetup } from "@decocms/start/setup";
import { applySectionConventions } from "@decocms/start/cms";

import blocks from "./server/cms/blocks.gen";
import sectionsGen from "./server/cms/sections.gen";
import meta from "./server/cms/meta.gen.json";

createSiteSetup({
  sections: import.meta.glob("./sections/**/*.tsx", { eager: true }),
  blocks,
  meta: () => meta,
  productionOrigins: ["https://my-store.com"],
});

applySectionConventions(sectionsGen);

src/worker-entry.ts

import "./setup";   // MUST be first

import { createDecoWorkerEntry } from "@decocms/start/sdk/workerEntry";
import {
  handleMeta,
  handleDecofile,
  handleRender,
  handleInvoke,
} from "@decocms/start/admin";
import serverEntry from "./server";

export default createDecoWorkerEntry(serverEntry, {
  admin: { handleMeta, handleDecofile, handleRender, handleInvoke },
});

src/routes/$.tsx

import { createFileRoute } from "@tanstack/react-router";
import { cmsRouteConfig } from "@decocms/start/routes";

export const Route = createFileRoute("/$")(
  cmsRouteConfig({ siteName: "my-store" }),
);

That is the entire skeleton. npm install, npm run dev, point admin.deco.cx at it, and you have a working CMS-driven site.

For commerce integrations (VTEX, Shopify) see @decocms/apps.


Migrating from Fresh / Preact / Deno

@decocms/start ships an Agent Skill that handles the migration for you. It works with Claude Code, Cursor, Codex, and any tool that supports skills.

npx skills add decocms/deco-start

Then, in your editor, point at your Fresh storefront and prompt:

migrate this project to TanStack Start

The skill runs the migration script, walks you through MIGRATION_REPORT.md, fixes typecheck/build errors interactively, and shows the diff before committing.

Or run the script directly

# from inside the v1 storefront directory
npx -p @decocms/start deco-migrate

The script runs seven phases (analyze β†’ scaffold β†’ transform β†’ cleanup β†’ report β†’ verify β†’ bootstrap), produces MIGRATION_REPORT.md with manual TODOs, and gets you to "compiles clean, builds clean".

Full migration playbook: docs.deco.cx/v2/en/migration/overview.


Documentation

The full v2 docs live at docs.deco.cx/v2:

  • Getting started β€” install paths, project structure, stack overview.
  • Concepts β€” sections, loaders, blocks, routes, deferred rendering.
  • Framework reference β€” every export of @decocms/start, page by page.
  • Migration β€” v1 β†’ v2 playbook + script + skill.
  • Case studies β€” three production stores end-to-end.

Peer dependencies

{
  "@tanstack/react-start": ">=1.0.0",
  "@tanstack/store": ">=0.7.0",
  "@tanstack/react-query": ">=5.0.0",
  "react": "^19.0.0",
  "react-dom": "^19.0.0",
  "vite": ">=6.0.0"
}

OpenTelemetry is optional but recommended: @microlabs/otel-cf-workers >=1.0.0-rc.0, @opentelemetry/api >=1.9.0.


Development

npm run typecheck   # tsc --noEmit
npm run lint        # biome check
npm run check       # typecheck + lint + unused exports

This is a library β€” there is no dev server here. Consumer storefronts run their own vite dev.

Contributing? See CLAUDE.md for the architectural decisions, and MIGRATION_TOOLING_PLAN.md for the append-only history of the migration tooling.


License

MIT

About

Deco framework for TanStack Start - CMS bridge, admin protocol, hooks, schema generation

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors