brainstorming
brainstorming
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or planning anything new, in software or out of it (a talk, a business, a renovation).
craftcms-opsCraft CMS 3/4/5 agency site builds: Matrix-as-entries content modeling, Twig and element queries, eager loading, output escaping and CSRF, and the usual plugin stack - SEOmatic, Blitz, Formie, CKEditor, craft-vite - plus DDEV, Codeception, image transforms, the queue, and 3-to-4-to-5 upgrades. Use when building, debugging, securing, speeding up, or upgradin…
Independent GitHub snapshot · Automated classification · Original documentation governs
Versions verified 2026-10-05 against Packagist and the official docs. Craft 5.x is current (5.11); Craft 4 and 3 are past security support; Craft 6 is in alpha.
scripts/check-craft-facts.py --livere-checks the plugin majors on a schedule.
The recurring agency shape: Craft 5 (or a 4/3 site awaiting upgrade) on DDEV, with SEOmatic, Blitz, Formie, and CKEditor, a Vite (or legacy Laravel Mix) front end, and modules tested with Codeception and ECS. This file is the procedure and the router; each topic lives in one reference.
| Check | Where | Tells you |
|---|---|---|
| Craft + plugin versions | composer.json, ddev composer show craftcms/cms | Which line of the version matrix applies - Craft 4 and 5 APIs differ |
| Local environment | .ddev/config.yaml | PHP/DB versions; run everything as ddev craft, ddev composer, ddev npm |
| Schema | config/project/*.yaml | Source of truth for sections, fields, entry types, plugin settings |
| Config | config/general.php, config/<plugin>.php, .env | Environment-specific behaviour (devMode, allowAdminChanges, caching) |
| Front-end build | package.json + config/vite.php, or webpack.mix.js | craft-vite or Laravel Mix |
| Templates | templates/_layouts, _partials, _partials/entry/<type>.twig | Layout inheritance and element partials |
| PHP | modules/, tests/, codeception.yml, ecs.php | Where logic and tests live |
| Page cache | config/blitz.php, Blitz utility | Whether what you see is cached HTML - check before debugging "my change isn't showing" |
| Task | Read |
|---|---|
| Listing pages, relations, Matrix/nested entries, pagination, multi-site | element-queries.md |
| Printing anything user-influenced, forms that POST, JS data, rich text output | twig-security.md |
| Meta tags, JSON-LD, sitemaps, robots.txt, hreflang | seomatic.md |
| Static caching, "changes don't show", cache warming, dynamic bits on cached pages | blitz.md |
| Building, theming, or debugging forms; spam; form emails not sending | formie.md |
| Rich-text fields, nested entries inside rich text, Redactor conversion | ckeditor.md |
Craft on DDEV: the craftcms type, ddev craft, Craft's upload_dirs (generic DDEV: ddev-ops) | ddev.md |
| Tests for modules/plugins, fixtures, ECS/PHPStan | codeception.md |
| Front-end assets, Vite dev server, critical CSS | craft-vite.md |
| Moving off Laravel Mix/Webpack, or Vue 2 to Vue 3 | frontend-upgrade-ops (the full migration playbook) |
| Upgrading Craft 3 → 4 → 5, plugin version lines, Craft 6 status | upgrades.md |
| Slow pages, images, queue setup, production config | performance.md |
| Core Web Vitals failing (LCP, INP, CLS), PageSpeed or Search Console flags | web-perf-ops (field data first; its references/craft.md maps the Craft levers) |
| Headless front ends, GraphQL schemas and tokens | graphql.md |
| Modules, plugins, events, migrations, queue jobs | plugin-development.md |
| Modeling a new flexible page type | assets/entry-type-field-layout.md |
.with([...]) up front; .eagerly() inside shared
partials (Craft 5 only). One query per card is the most common Craft perf bug.|raw user-influenced values; |e('js') inside JS
strings; {{ csrfInput() }} in every POST form - csrfInput({ async: true }) on
cached pages.config/project/, run php craft up on deploy. Production runs
allowAdminChanges => false; never hand-edit the YAML.php craft migrate/create), tested on a
copy of production - not CP clicking on live.{% cache %} (or set enableTemplateCaching false).| Package | Craft 3 | Craft 4 | Craft 5 (current) |
|---|---|---|---|
craftcms/cms | 3.9 (EOL) | 4.18 (EOL Apr 2026) | Craft 5.x (5.11); Craft 6 in alpha |
nystudio107/craft-seomatic | 3.x | 4.x | SEOmatic 5 |
putyourlightson/craft-blitz | 3.x | 4.x | Blitz 5 (5.13 needs Craft 5.6+) |
verbb/formie | 1.x | 2.x | Formie 3 (Formie 4 in beta) |
| Rich text | Redactor | Redactor or craftcms/ckeditor 3.x | CKEditor plugin 5.x (needs Craft 5.10+; 4.x below that) |
nystudio107/craft-vite | 1.x | 4.x | craft-vite 5 |
nystudio107/craft-imageoptimize | 1.x | 4.x | ImageOptimize 5 |
spacecatninja/imager-x | 3.x | 4.x | Imager-X 6 (5.x still maintained) |
codeception/codeception | match core's require-dev | match core's require-dev | Codeception 5 |
Requirements for Craft 5: PHP 8.2+, MySQL 8.0.17+ / MariaDB 10.4.6+ / PostgreSQL 13+. Details and plugin upgrade notes: upgrades.md.
Command (prefix ddev locally) | Does |
|---|---|
craft up | Pending migrations + Project Config - run on every deploy |
craft project-config/apply / project-config/rebuild | Apply YAML to the DB / rebuild YAML from the DB |
craft clear-caches/all | Data, template, and asset caches |
craft queue/run / queue/info / queue/retry all | Work and inspect the queue |
craft blitz/cache/refresh | Refresh Blitz after template deploys (Blitz tracks content, not templates) |
craft migrate/create <name> | New content migration |
craft make <type> | Scaffold modules/plugins/components (craftcms/generator) |
craft entrify/categories <group> | Convert categories (or tags, global-set) to entries |
| Concept | What it is | Craft 5 change |
|---|---|---|
| Section | Single, Channel, or Structure; holds entry types + URI formats | - |
| Entry type | The unit of content shape | Global and reusable across sections and Matrix fields |
| Field | Reusable input | Global, with multi-instance use in one layout |
| Matrix field | Repeatable nested content | Stores nested entries, not blocks |
| CKEditor field | Rich text | Can hold nested entries inline |
| Element partials | _partials/entry/<typeHandle>.twig | .render() renders nested entries through them |
| Project Config | config/project/ YAML | Source of truth - commit it |
Pick the section type by shape: Single for one-off pages (home, contact), Channel for streams (news, events), Structure for hierarchies (pages, docs). Prefer flat entry types plus a Matrix "page builder" field over many near-identical sections. Starter shape: entry-type-field-layout.md.
| Symptom | Cause | Fix |
|---|---|---|
| Listing page runs hundreds of queries | Relation fetched per item | .with() / .eagerly() |
| Change visible in CP, not on site | Blitz/CDN serving cached HTML | blitz.md |
| Form submissions save, emails never send | Queue not running in production | Queue daemon (performance.md) |
| Assets unstyled in production only | Vite 5+ manifest is in dist/.vite/ | Set manifestPath (craft-vite.md) |
{% set seomatic.meta.seoTitle = ... %} does nothing | set only reads | {% do seomatic.meta.seoTitle('...') %} |
| Staging copy of the site got indexed / prod de-indexed | SEOmatic environment wrong | Check robots in view-source (seomatic.md) |
| Project Config conflicts between developers | CP edits on shared/prod environments | allowAdminChanges false outside local; one schema change per PR |
| Event handler fires several times per save | Drafts, revisions, propagation | Guard with ElementHelper::isDraftOrRevision() + propagating |
craft.matrixBlocks() errors after upgrade | Removed in Craft 5 | craft.entries().field(...).owner(...) |
| File | Use |
|---|---|
assets/entry-type-field-layout.md | Content-modeling starter: section + entry type + Matrix-as-entries, mapped to Project Config |
assets/craft-facts.json | The version facts this skill documents (package, major, prose token) |
scripts/check-craft-facts.py | Staleness verifier: --offline (prose still states the facts) / --live (Packagist majors) |
ddev-ops (generic DDEV: version pinning, env files, snapshots and sanitised pulls,
Mutagen, add-ons, Xdebug, and an auditor for .ddev/ mistakes)laravel-ops (Composer/PHP tooling; Craft 6 is Laravel-based) · sql-ops (indexes behind
slow orderBy) · nginx-ops (serving Craft, Blitz rewrites) · perf-ops (profiling) ·
tailwind-ops · playwright-ops (browser tests against the DDEV URL)web-perf-ops (Core Web Vitals: CrUX/RUM first, then the failing subpart; Blitz, transforms,
craft-vite critical CSS and SEOmatic/Formie script placement as INP/LCP levers)frontend-upgrade-ops (Laravel Mix or Webpack to Vite via craft-vite, Vue 2 to Vue 3,
Vue islands in Twig, and when a widget should become Alpine instead)a11y-ops (WCAG 2.2 for Twig sites: heading levels across partials, asset alt text, Formie
and CKEditor markup, multi-site lang; see its references/server-rendered-templates.md)security-ops (Craft/Twig/PHP security: CSRF and Formie, allowAnonymous, devMode and the
security key, GraphQL scoping, uploads, advisories and Craft 3/4 end of life; its
references/craft-*.md, twig-*.md, php-*.md)Why this shape: a 2026 survey of 57 Craft-agency repositories found Craft in 36 (Craft 5 ×17, 4 ×13, 3 ×6), DDEV in 36, SEOmatic in 33, Blitz 21, Formie 18, CKEditor 18, Laravel Mix 18 versus craft-vite 12, Tailwind 12, ECS 11, and Codeception 10. The references follow that frequency; upgrades matter because half the Craft sites were on an EOL major.