Migrate script
What npx -p @decocms/blocks-cli deco-migrate actually does.
@decocms/blocks-cli provides deco-migrate for migrating a retired Fresh/Deno site to the released Blocks 7.x TanStack binding. This page documents what it does, what flags it accepts, and what it doesn't.
Quick start
# from your v1 site directory
npx -p @decocms/blocks-cli deco-migrateThat's it. The script analyzes the source layout, scaffolds Blocks 7.x files, transforms imports/JSX/APIs, cleans up dead code, generates a report, verifies the result, and bootstraps deps.
Flags
| Flag | Purpose |
|---|---|
--source <dir> | Source directory (default: current directory) |
--dry-run | Preview changes without writing files |
--verbose | Show detailed output for every transformation |
--no-compile | Skip the post-transform tsc --noEmit + vite build step |
--no-cleanup-audit | Skip the post-migration audit (read-only sanity check) |
--strict | Fail the run on any cleanup audit warning |
--with-build | Run a full vite build (default is typecheck only) |
--help, -h | Show help |
The seven phases
Pulled from scripts/migrate.ts:
1. Analyze — scan source, detect Preact/Fresh/Deco patterns
2. Scaffold — generate vite.config.ts, wrangler.jsonc, routes, setup.ts, worker-entry
3. Transform — rewrite imports (70+ rules), JSX attrs, Fresh APIs, Deno-isms, Tailwind v3→v4
4. Cleanup — delete islands/, old routes, deno.json, move static/ → public/
5. Report — generate MIGRATION_REPORT.md with manual review items
6. Verify — 18+ smoke tests (zero old imports, scaffolded files exist)
7. Bootstrap — Bun install, generate CMS blocks, generate routes
After phase 7, the script optionally:
- Compiles (
--no-compileto skip): runstsc --noEmitand (with--with-build)vite build. Compile failures are reported but don't fail the migration unless--strict. - Cleanup audit (
--no-cleanup-auditto skip): a read-only audit of leftover Fresh patterns. Surfaces things like leftovercompat/folders or strayuseScript(fn)calls.
Layout detection
Phase 0 accepts classic Fresh projects with sections/, islands/, and related directories at the repository root, and modern projects with those directories under src/. Both layouts are scanned natively.
A mixed layout (both populated root and src/ directories) or an empty layout aborts before migration writes begin. Check the source path or restore a clean source checkout rather than rearranging a supported src/ layout. A dry run uses the same preflight.
What MIGRATION_REPORT.md contains
After a real run, the report has:
- Run mode (DRY_RUN or EXECUTED) and timestamp.
- File counts — scaffolded, transformed, deleted.
- Full file lists for each category.
- Loader inventory — every
loaders/*.tsandactions/*.tsfound, with port status. - Tailwind v3 → v4 pitfalls — negative
z-index, opacity migrations,@applyrewrites. @decocms/blocksboilerplate duplication — places where the migrated code overlaps with framework-provided helpers (candidates for cleanup).- Concrete next steps — exact commands to run.
The report is written at the site root. Review it and commit it with the migration so reviewers can inspect what changed.
Configuration file
You can pin script behavior via .deco-migrate.config.json at your project root:
{
"sectionConventions": {
"extend": {
"eagerSync": ["Header"],
"sync": ["Hero"],
"listingCache": ["ProductShelf"],
"staticCache": ["Footer"]
}
}
}extend adds section file names to the defaults; replace uses only your lists. This file does not implement exclude, skipPhases, or verbose; use the documented CLI flags and review the migration diff. See section conventions.
Companion scripts
deco-post-cleanup
Run after the migration to clean up leftover boilerplate the framework has since absorbed:
npx -p @decocms/blocks-cli deco-post-cleanupThis is read + write — review the diff before committing.
deco-htmx-analyze
Specifically for sites that used HTMX during the v1 era. Reports HTMX usage so you can plan the conversion to React patterns. HTMX is not shipped in @decocms/blocks — sites that depended on it need to rewrite to React.
npx -p @decocms/blocks-cli deco-htmx-analyzeWhat the script doesn't do
- Doesn't migrate
useCart/useUser/useWishlistoverrides. If your v1 site monkey-patched these, you'll need to port the overrides manually using the v2 hook factories. See VTEX hooks. - Doesn't migrate custom worker logic. Custom proxies, A/B harnesses, edge transforms — the script generates a vanilla
worker-entry.tsand leaves you to layer custom logic on top usingcreateDecoWorkerEntry. - Doesn't fix runtime correctness. A successful migration produces compiling code; runtime issues (cart not loading, PDP showing wrong product, hydration mismatches) need human attention.
- Doesn't translate non-storefront sites. The script is tuned for the deco.cx storefront archetype. Marketing sites with very custom Fresh setups should expect more manual work.
Troubleshooting
"Layout not classic — aborting"
The current migrator accepts root and src/ layouts. For mixed or empty input, verify --source and restore a complete source checkout; read the specific CLI diagnostic before changing directories.
tsc --noEmit fails after migration
Read MIGRATION_REPORT.md. Common culprits:
- A platform hook (
useCart, etc.) that needs site-specific implementation. - A
useScript(fn)that the script transformed but the calling code doesn't accept. - A custom matcher or loader that uses Deno-only APIs.
vite build fails
Run with --with-build to surface this during migration. Then read the error — most are missing imports caused by an island that was deleted but still referenced.
Production deploy works but admin preview is broken
You probably moved admin handlers into the TanStack server entry instead of the worker entry. See Worker entry reference.