frontend-upgrade-ops
Upgrade a server-rendered Craft CMS/Twig front end: Laravel Mix or Webpack to Vite via craft-vite (manifest, DDEV dev server, HMR, Tailwind v3, legacy builds…
Skill by claude-mods
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/0xdarkmatter-frontend-upgrade-ops
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: frontend, backend
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md and code. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
- Runs as
- Python package
Network hosts it talks to 2
codeload.github.com· found in install commandrepo.packagist.org· found in code
Files it touches
~/.claude/skills/frontend-upgrade-ops
Tools it pre-approves 6
From allowed-tools in SKILL.md: the agent may use these without asking you each time.
ReadEditWriteBashGlobGrep
What's inside
- Skill name
frontend-upgrade-ops- Description
- Upgrade a server-rendered Craft CMS/Twig front end: Laravel Mix or Webpack to Vite via craft-vite (manifest, DDEV dev server, HMR, Tailwind v3, legacy builds, Twig asset URLs) and Vue 2 to Vue 3 (@vue/compat, Vuex to Pinia, plugin swaps, Vue islands in Twig). Use when a site still has webpack.mix.js, mix-manifest.json or Vue 2, or when deciding if a small Vue widget should become Alpine.js or vanilla JS instead.
- License
- MIT
- Allowed tools
- Read, Edit, Write, Bash, Glob, Grep
- Metadata
- author: claude-mods · related-skills: migrate-ops, vue-ops, craftcms-ops, ddev-ops, web-perf-ops, tailwind-ops, playwright-ops, security-ops, package-manager-ops
- Instructions
- 192 lines in SKILL.md · view on GitHub
Before installing
- Ships executable scripts
- Pre-approves any shell command
Files (9)
- SKILL.md
- frontend-upgrade-facts.json · assets/
- craft-vite-twig.md · references/
- mix-webpack-to-vite.md · references/
- vue-islands-in-twig.md · references/
- vue-state-and-plugins.md · references/
- vue2-to-vue3.md · references/
- check-frontend-upgrade-facts.py · scripts/
- run.sh · tests/
SKILL.md (first lines)
# Frontend Upgrade Operations
The two front-end upgrades a Craft CMS (or any Twig/PHP) agency keeps meeting: an asset
pipeline still on **Laravel Mix or raw Webpack**, and widgets still on **Vue 2**. Both
are frozen - Mix's last release was 6.0.49 in June 2022 and Laravel calls it "a legacy
package that is no longer actively maintained"; Vue 2 reached end of life on
31 December 2023. This skill is the playbook for moving a server-rendered site to
**Vite 8 + craft-vite** and **Vue 3**, or for deciding that a widget should not be Vue
at all.
> Version facts verified as of 2026-10-05 against npm, Packagist, vite.dev,
> v3-migration.vuejs.org and nystudio107.com/docs/vite. Each reference cites its sources.
## Start here: what does this repo need?
| You find | Do | Read |
|---|---|---|
| `webpack.mix.js`, `mix-manifest.json`, `mix()` in Twig | Replace Mix with Vite + craft-vite | [mix-webpack-to-vite.md](references/mix-webpack-to-vite.md), then [craft-vite-twig.md](references/craft-vite-twig.md) |
| A hand-written `webpack.config.js` | Same move; translate loaders and plugins one by one | [mix-webpack-to-vite.md](references/mix-webpack-to-vite.md) |
| craft-vite already, but the dev server fails behind DDEV | CORS / `allowedHosts` / one port in four places | [craft-vite-twig.md](references/craft-vite-twig.md#troubleshooting) |
| `"vue": "^2` in `package.json` | Decide per widget: migrate or replace (table below) | this file, then [vue2-to-vue3.md](references/vue2-to-vue3.md) |
| Mix **and** Vue 2 | Bundler first, framework second - never one deploy | [Sequencing](#sequencing-both-upgrades) |
| `vuex`, `vue-router` 3, Vue 2-only plugins | Pinia; check every plugin for a Vue 3 path before estimating | [vue-state-and-plugins.md](references/vue-state-and-plugins.md) |
| Vue templates written in Twig (`inline-template`, in-DOM) | Convert to SFC islands; mind the compiler build and template injection | [vue-islands-in-twig.md](references/vue-islands-in-twig.md) |
| Vue 3 + Vite already | Out of scope here - steady-state Vue is `vue-ops`, steady-state Craft is `craftcms-ops` | - |
## Migrate Vue, or replace it?
Most agency Vue 2 code is not an app; it is a handful of widgets. Migrating a widget
that a dozen lines of Alpine would do costs more than replacing it. Decide **per
island**, before estimating the migration.
| The widget is... | Verdict | Why |
|---|---|---|
| Toggle, accordion, tabs, mobile nav, show/hide | **Native HTML or Alpine.js** | `<details>`, `<dialog>`, `popover` cover much of it with zero JS; the rest is a boolean in `x-data` written straight into Twig |
| A form with validation and a submit spinner | **Alpine** + native constraint validation | No component tree, no store; Alpine keeps the markup in Twig where editors expect it |
| A thin wrapper around a framework-free library (slider, date picker, map, lightbox) | **Vanilla JS or Alpine** calling the library directly | The Vue wrapper was the only Vue 2-specific part |
| Renders server data and never changes it | **Delete it; render in Twig** | It's a template, not an app |
| Filtering/sorting a list with derived counts, several child components | **Vue 3** | Computed state and components earn their weight |
| Several islands sharing state (cart, saved items, auth) | **Vue 3 + Pinia** | A shared store across apps is what Vue + Pinia does well |
| Routing inside a section (multi-step tool, dashboard) | **Vue 3** (+ vue-router) | Alpine has no answer for this |
| Built on a Vue 2 UI kit with no Vue 3 release | **Rewrite budget**, Vue 3 or Alpine, decided by the rows above | The kit, not Vue, is the migration |
Rules of thumb for the grey zone: under ~150 lines with one level of state, Alpine
wins; any use of Vuex, a router, or more than two child components, Vue 3 wins. A site
that ends up with both is normal - see the Alpine coexistence rules in
[vue-islands-in-twig.md](references/vue-islands-in-twig.md#coexisting-with-alpine-sprig-and-page-caches).
## Sequencing both upgrades
Each numbered step is a separate deploy with its own parity check. Combining the
bundler swap with the framework swap is the classic mistake: when a page breaks you
cannot tell which change did it.
```
0. Inventory rg the repo (below); list page types that render JS widgets
1. Vue 2.7.16 if on Vue 2.6 - backports Composition API + <script setup>
2. Mix -> Vite still on Vue 2: Vite 7.3 + @vitejs/plugin-vue2
(plugin-vue2's peer range ends at vite ^7.0.0 as of 2026-10-05;
Vite 7.3 still gets important fixes + security patches)
3. Replace widgets the table above says shouldn't be Vue -> Alpine/vanilla
4. Vuex -> Pinia 2 (optional, still on Vue 2.7; Pinia 3+ dropped Vue 2)
5. Vue 3 @vue/compat on Vite 8 + @vitejs/plugin-vue; burn down warnings
6. Drop compat then Pinia 4, then remove @vitejs/plugin-legacy if analytics allow
```
No Vue on the site? Steps 1, 3-6 vanish: go straight to Vite 8.
If Vue 2 must die first (a security finding, a hosting rule), the order flips: Vue 3
via `@vue/compat` **on Webpack** is supported by the migration guide, then Vite. It is
the slower path - two configurations of Vue 3 tooling instead of one.
```bash
# Step 0 - inventory in one pass
fd -H "webpack.mix.js|webpack.config.js|mix-manifest.json|vite.config" -E node_modules
jq '{vue:.dependencies.vue, mix:.devDependencies["laravel-mix"], webpack:.devDependencies.webpack, vite:.devDependencies.vite, vuex:.dependencies.vuex}' package.json
rg -n "mix\(|craft\.vite|data-vue-island|inline-template|new Vue\(" templates/ src/ | head -50
```
## Cutover checklist: Mix/Webpack to Vite
Work top to bottom; each line links to the detail.
- [ ] Branch from a green build; record a **parity baseline** - screenshots of every
page type + the network panel's JS/CSS list on the Mix build, plus lab LCP/CLS/TBT
for the key templates (median of 5 runs, method in `web-perf-ops`)
- [ ] `npm pkg set type="module"` (or name configs `.mjs`/`.cjs` explicitly)
- [ ] `vite.config.js`: `base`, `build.manifest`, `outDir: web/dist`, entries in
`build.rolldownOptions.input` ([config](references/mix-webpack-to-vite.md#a-viteconfigjs-for-a-craft-site))
- [ ] Every `webpack.mix.js` call mapped ([translation table](references/mix-webpack-to-vite.md#translate-the-mix-api))
- [ ] Source rewrites: `require`, `require.context`, `.vue` extensions, `process.env`,
`MIX_` to `VITE_`, Sass `~` imports ([rewrites](references/mix-webpack-to-vite.md#source-rewrites))
- [ ] `postcss.config.js` + `tailwind.config.js` load; `content` globs still find
`templates/**/*.twig` - **stay on Tailwind v3** for this deploy
- [ ] `composer require nystudio107/craft-vite` (5.x Craft 5, 4.x Craft 4); `config/vite.php`
with `manifestPath` = `@webroot/dist/.vite/manifest.json`
- [ ] DDEV: the same port in `web_extra_exposed_ports`, `server.port`, `server.origin`,
`devServerPublic`; `cors` + `allowedHosts` for `.ddev.site`
([DDEV](references/craft-vite-twig.md#dev-server-through-ddev))
- [ ] Twig: every `mix()` / hard-coded `/js/`, `/css/` tag replaced with
`craft.vite.script(...)`; main CSS with `asyncCss = false` unless critical CSS exists
- [ ] Inline scripts that used bundle globals at parse time fixed (module scripts are
deferred) ([why](references/craft-vite-twig.md#twig-replacing-the-mix-tags))
- [ ] Twig-referenced images resolved via `craft.vite.asset()` or left in `web/`
- [ ] Legacy build: decided from analytics, `@vitejs/plugin-legacy` only if needed
([legacy](references/mix-webpack-to-vite.md#legacy-browser-builds))
- [ ] HMR works for CSS + JS; Twig edits reload (`vite-plugin-restart`)
- [ ] `vite build` in CI/deploy; `web/dist/` gitignored; no hashed files committed
- [ ] Parity check against the baseline: every page type, fonts, icons, console clean,
and the lab metrics - async CSS and `modulepreload` move LCP and CLS
(`web-perf-ops` has the LCP/CLS fixes)
- [ ] Deploy keeps the previous build until full-page caches are purged
- [ ] Delete `webpack.mix.js`, `mix-manifest.json`, old `web/js` + `web/css`,
`laravel-mix` and webpack-only devDependencies - in a follow-up commit
## Vue 2 to 3 at a glance
The full workflow, the breaking-change table and testing live in
[vue2-to-vue3.md](references/vue2-to-vue3.md). The shape:From 0xDarkMatter/claude-mods, MIT.
More from 0xDarkMatter/claude-mods
- 0.654score
claude-api-ops
claude-mods
Building applications ON Claude - the Anthropic API and Claude Agent SDK.
SkillAFreshness: A★ 75Claude Code - 0.654score
git-ops
claude-mods
Git + worktree orchestrator: status survey, per-worktree triage, commits, PRs, branches, releases, rebases — reads inline, writes to a background agent.
SkillAFreshness: A★ 75Claude Code +9 - 0.654score
bash-ops
claude-mods
Defensive Bash scripting for production automation, CI scripts, and agent-facing tools.
SkillAFreshness: A★ 75Claude Code +9 - 0.654score
loop-ops
claude-mods
Design and safely run OUTER loops - scheduled discover-triage-implement-verify-escalate agent loops.
SkillAFreshness: A★ 75Claude Code +9 - 0.654score
a11y-ops
claude-mods
Web accessibility end to end: WCAG 2.2 AA, EAA and ADA Title II obligations, audits (axe, pa11y, keyboard, screen reader), the common failures, accessibility…
SkillAFreshness: A★ 75Claude Code +9 - 0.654score
adr-ops
claude-mods
Author, index, and lint Architecture Decision Records — append-only memory that recovers the WHY behind a system's shape.
SkillAFreshness: A★ 75Claude Code +9 - 0.654score
fleet-ops
claude-mods
Landing discipline for parallel work: sequential test-gated landing queue, pre-land scrub, auto-rebase of in-flight lanes, fleet status, one-shot revert…
SkillAFreshness: A★ 75Claude Code +9 - 0.654score
auto-skill
claude-mods
Evaluate current session for skill-worthy workflows and create reusable skills.
SkillAFreshness: A★ 75Claude Code +9 - 0.654score
asus-router-ops
claude-mods
ASUS router config and hardening: Asuswrt-Merlin, security hardening, encrypted DNS (DoT/DoH), VPN (WireGuard/OpenVPN), guest networks, VLAN/IoT isolation…
SkillAFreshness: A★ 75Claude Code +9 - 0.654score
atomise
claude-mods
Atom of Thoughts (AoT) reasoning - decompose complex problems into atomic units with confidence tracking and backtracking.
SkillAFreshness: A★ 75Claude Code +9 - 0.654score
auth-ops
claude-mods
Authentication and authorization patterns - JWT, OAuth2, sessions, RBAC, ABAC, passkeys, MFA, identity-aware proxies, and Better Auth.
SkillAFreshness: A★ 75Claude Code +9 - 0.654score
claude-code-ops
claude-mods
Claude Code internals - hooks, skill frontmatter, headless mode, and extension debugging, current as of June 2026.
SkillAFreshness: A★ 75Claude Code +9
Signals
- Stars
- 75
- Forks
- 8
- Open issues
- 0
- Last commit (this folder)
- Oct 7, 2026 (23 days ago)
- Last release
- Oct 14, 2026 (15 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/0xDarkMatter/claude-mods
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from claude-mods
- 0.685score
file-search
claude-mods
Modern file and content search using fd, ripgrep (rg), and fzf.
SkillCFreshness: C★ 443Claude Code +9 - 0.685score
code-stats
claude-mods
Analyze codebase with tokei (fast line counts by language) and difft (semantic AST-aware diffs).
SkillCFreshness: C★ 443Claude Code +9 - 0.685score
sqlite-ops
claude-mods
Patterns for SQLite databases in Python projects - state management, caching, and async operations.
SkillCFreshness: C★ 443Claude Code +9 - 0.685score
project-planner
claude-mods
Detects stale project plans and suggests session commands.
SkillCFreshness: C★ 443Claude Code +9 - 0.685score
python-env
claude-mods
Fast Python environment management with uv (10-100x faster than pip).
SkillCFreshness: C★ 443Claude Code +9 - 0.685score
container-orchestration
claude-mods
Docker, Kubernetes, and AWS ECS/Fargate patterns.
SkillCFreshness: C★ 443Claude Code +9
Cite this page
frontend-upgrade-ops skill. Agent Mart. https://agentmart.dev/skills/0xdarkmatter-frontend-upgrade-ops (last updated 2026-10-24)