Chat on WhatsApp
Hyvä Theme 11 min read

Hyvä Module Compatibility Checker — Manual Grep + Automated CLI

There are two honest ways to check whether a Magento extension is Hyvä-compatible — manual grep across the module source, and the hyva-themes/magento2-compatibility-checker CLI. Neither one catches everything. This post lists the exact bash one-liners I run against vendor/, walks through what the official Hyvä compat CLI flags and what it silently ignores (Magewire deps, GraphQL schema needs, form validation libs), and ends with the checklist I work through when the CLI prints "compatible" but the module still throws KO errors in the Hyvä storefront on Magento 2.4.4 — 2.4.9.

Hyvä Module Compatibility Checker — Manual Grep + Automated CLI

Buying a Magento extension off the Marketplace and dropping it into a Hyvä storefront is a coin flip. The vendor's compatibility badge usually means "works on Luma" — Hyvä strips Knockout, jQuery, and RequireJS out of the storefront, and any module built around those three will break the moment a customer hits the page. The fix is to audit the module before you install it, and there are exactly two methods worth using on Magento 2.4.4 — 2.4.9.

Two audit methods cover 90% of the risk before the module is installed.

The first method is manual grep against the module source. The second is the official hyva-themes/magento2-compatibility-checker CLI[1]. Each one catches a different slice of the incompatibility surface. Used together, they catch about 90% of the modules that would otherwise break in production — the remaining 10% needs the manual review checklist at the end of this post.

On kishansavaliya.com we audit 6–10 extensions per Hyvä migration sprint using the workflow below.

A Hyvä-compatible module is one that renders correctly with Knockout, jQuery, and RequireJS all absent.

1. Manual grep — the five-minute pre-check

Manual grep is the cheapest first pass. Before you composer require anything, clone the module source (most vendors ship a public GitHub or you can extract the zip from the Marketplace download) and run three one-liners against it. Each one targets a specific Hyvä incompatibility surface.

One-liner A — find Knockout templates

grep -RnE 'data-bind="' app/code vendor/<extension>

Any hit means the module ships a Knockout-bound HTML template. Hyvä does not load knockout.js on the frontend, so every data-bind attribute will render as plain HTML with no behavior. A module with 12+ hits in view/frontend/web/template/*.html needs a full Magewire or Alpine rewrite — quote the rewrite, do not promise compatibility.

# Realistic output against a typical Luma-only checkout extension
vendor/acme/module-deliverydate/view/frontend/web/template/delivery-date.html:3:        <input data-bind="value: deliveryDate, attr: {id: getInputId()}"
vendor/acme/module-deliverydate/view/frontend/web/template/delivery-date.html:7:        <p data-bind="text: errorMessage" class="field-error"></p>
vendor/acme/module-deliverydate/view/frontend/web/template/summary.html:2:    <span data-bind="text: $parent.deliveryDate()"></span>

One-liner B — find RequireJS dependencies

grep -Rn 'requirejs-config.js' app/code vendor/<extension>

This locates every requirejs-config.js the module ships. Hyvä does not load RequireJS, so anything registered through config.map or config.mixins in those files will silently never run. The same grep with a wider net (grep -RnE 'define\(\[|require\(\[') shows the actual JS modules that depend on RequireJS for loading.

vendor/acme/module-deliverydate/view/frontend/requirejs-config.js
vendor/acme/module-deliverydate/view/frontend/web/js/view/delivery-date.js

If the module ships a mixin (RequireJS config.mixins) over a core Magento JS file like Magento_Checkout/js/view/shipping, that is a Luma-only injection point. Hyvä replaces those checkout surfaces with Magewire components — the mixin does not run anywhere.

One-liner C — find phtml that already plays nice with Hyvä's ViewModel pattern

find . -name "*.phtml" -exec grep -l "\$block->getViewModel" {} \;

Hyvä's frontend pattern depends on PHP-side ViewModels rather than JavaScript components. A module that already uses $block->getViewModel() in its phtml is one or two hours from being Hyvä-compatible. A module that does all data prep in JS is one or two weeks away.

./vendor/acme/module-priceformat/view/frontend/templates/price.phtml
./vendor/acme/module-priceformat/view/frontend/templates/list.phtml

Two hits is encouraging. Zero hits and a view/frontend/web/js/ directory full of uiComponent code means the module is structurally Luma-only.

Two more greps worth running

grep -Rn 'jQuery\|\$(' vendor/<extension>/view/frontend/web/js | head
grep -Rn 'customerData\.get' vendor/<extension> | head

jQuery references are a red flag — Hyvä does not ship jQuery. The customerData.get grep finds modules that hook into Magento's customer-section invalidation pattern, which on Hyvä is replaced with Magewire's $wire.refresh or Alpine's x-data watchers. Both patterns require porting.

Manual grep takes about five minutes per module, scales linearly with how many modules the project ships, and gives you a defensible gut check before paying for a deeper audit.

2. The official Hyvä compat CLI — the 30-second confirmation

The hyva-themes team ships an actively maintained CLI that automates everything above and adds a deprecated-API scan on top[1]. It is the right second step after manual grep.

Install

composer require --dev hyva-themes/magento2-compatibility-checker
bin/magento setup:di:compile
bin/magento hyva:compat:check Vendor_Module

The CLI registers a single Magento command — hyva:compat:check — that accepts a module name (the same string you would pass to bin/magento module:enable) and walks every file under that module's directory.

Real output

$ bin/magento hyva:compat:check Acme_DeliveryDate

Acme_DeliveryDate — Hyvä compatibility report
=============================================

[INCOMPATIBLE] KO templates found
  view/frontend/web/template/delivery-date.html — uses data-bind
  view/frontend/web/template/summary.html — uses data-bind

[INCOMPATIBLE] RequireJS modules found
  view/frontend/requirejs-config.js — registers ko-component-mixin
  view/frontend/web/js/view/delivery-date.js — defined as uiComponent

[WARNING] Layout XML references checkout.root with KO jsLayout
  view/frontend/layout/checkout_index_index.xml

[OK] No deprecated Magento_Ui form elements detected
[OK] No legacy prototypejs references found

Result: 4 issues — module is NOT Hyvä-compatible without rewrite work.
Estimated effort: 12 — 20 hours (1 Magewire component, 2 templates, 1 layout port).

The CLI categorizes findings as INCOMPATIBLE (will break the storefront), WARNING (will work but is suspicious), and OK. The effort estimate at the bottom is heuristic — it is calibrated against Hyvä Themes' internal porting work and matches our own data within ±25%.

What it catches

  • Knockout templates (data-bind in HTML).
  • Knockout JS components (define([... ko ...]) patterns).
  • RequireJS configuration and mixins.
  • Deprecated Magento_Ui form elements that Hyvä's hyva_checkout does not implement.
  • Layout XML referring to Luma checkout containers (checkout.root, minicart's KO drawer).
  • Legacy prototypejs and scriptaculous references (still ship in 2 or 3 old extensions).

What it misses

This is the part vendors do not advertise. The CLI walks the module's source — if the incompatibility comes from a runtime dependency on a different package, the CLI cannot see it.

  • Magewire dependencies — if your storefront has Magewire installed and the module assumes vanilla Hyvä, mounting a Magewire component over its block can crash with "component already mounted". The CLI cannot detect cross-module Magewire conflicts.
  • GraphQL schema needs — modules built for headless Hyvä PWA Studio need a schema.graphqls with custom resolvers. The CLI does not check whether the headless schema exists.
  • Form validation libraries — Luma modules that ship mage/validation rules will pass the CLI silently (no KO, no RequireJS), but the form validation never fires on Hyvä because mage/validation is not loaded.
  • Customer-section invalidation — modules that rely on sections.xml to invalidate customer data on cart updates work on Luma, "work" on the CLI scan, and silently fail on Hyvä where the section pattern is replaced.
  • Third-party JS CDN injections — modules that load Stripe.js or Cloudflare Turnstile via requirejs-config.js need re-hooking through Hyvä's hyva_default_head_blocks_after layout. The CLI flags the RequireJS file but not the CDN dependency itself.

3. Audit method comparison — pick the right tool for the question

Audit methodCatchesMissesTime cost
Manual grep (3 one-liners)KO templates, RequireJS configs, ViewModel readiness, jQuery use, customerData hooksDeprecated UI components, layout container references, effort estimate~5 min/module
hyva:compat:check CLIEverything in grep + Magento_Ui deprecations + prototypejs/scriptaculous + effort estimateMagewire conflicts, GraphQL schema, form validation libs, customer-section runtime, CDN injection~30 sec/module
Manual review (checklist below)Everything the CLI misses, edge cases, business-logic surfacesRequires a Hyvä-experienced developer to run honestly~1–2 hr/module
Live render test on Hyvä stagingJS console errors, missing CSS, layout shiftsProduction-only conditions (B2B, multi-currency, multi-store)~30 min/module

For client work, run all four. For low-stakes dependencies, manual grep plus the CLI is enough.

4. What to do when the CLI says "compatible" but the module still breaks

This is the case the CLI cannot save you from. The compatibility scan returns 0 issues — module IS Hyvä-compatible, you install it, and the storefront throws a JS error on the first customer page load. The checklist below is what we run, in order, when that happens.

Step 1 — Check the browser JS console

Open the page in an incognito Chrome window with DevTools open. Filter the Console tab for "Uncaught". The first uncaught error is almost always the actual cause — anything after is downstream.

Uncaught ReferenceError: ko is not defined
    at acme-delivery-date.js:14

If you see ko is not defined, $ is not a function, or require is not defined, you have a Luma JS dependency that the CLI missed because it was loaded conditionally (via $.ajax response, dynamic import, or a runtime feature flag).

Step 2 — Check the Magento layout XML for Luma-only containers

grep -RnE 'referenceContainer name="(content\.aside|checkout\.root|minicart)"' vendor/<extension>

Modules that target Luma-specific containers like checkout.root (KO checkout) or minicart (KO drawer) will not render on Hyvä — Hyvä uses different container names and Magewire-rendered minicart. The fix is a layout XML override in the Hyvä theme that re-targets the container.

Step 3 — Look for Magewire registration conflicts

grep -Rn 'hyva_checkout_components.xml' vendor/<extension>

If two modules both register a component named checkout.shipping.delivery-date in hyva_checkout_components.xml, the second registration silently overrides the first, and the first module's PHP class never instantiates. Hyvä's component registry does not warn on duplicate names.

Step 4 — Check for missing GraphQL schema

// app/code/Vendor/Module/etc/schema.graphqls
extend type Query {
    deliveryDateOptions: [DeliveryDateOption] @resolver(class: "Vendor\\Module\\Model\\Resolver\\DeliveryDate")
}

type DeliveryDateOption {
    date: String
    label: String
}

If the storefront is headless (Next.js, PWA Studio, Vue Storefront), the module needs a GraphQL schema and resolver. A pure-Hyvä module with no schema.graphqls works for server-rendered Hyvä but breaks the headless layer.

Step 5 — Inspect the rendered HTML for orphan markup

<!-- ko if: hasDeliveryDate() -->
<div class="delivery-date-summary">
    <span data-bind="text: deliveryDate"></span>
</div>
<!-- /ko -->

<!-- ko --> KO control-flow comments render as actual HTML comments on Hyvä because Knockout is never loaded to interpret them. The wrapped markup is always visible, even when the condition would have been false. A view-source grep for <!-- ko finds every instance.

Step 6 — Validate form posts and customer-section invalidation

If the form does not POST in DevTools' Network tab, the submit handler depended on a Knockout binding or a mage/validation rule that never fired. The fix is an Alpine.js @submit.prevent or Magewire wire:submit.prevent that calls the same backend endpoint. For modules that show different content per customer group, Luma's sections.xml is dead code on Hyvä — the customer-specific content needs a Magewire component instead.

5. Next steps once you have the audit results

The two-step audit (grep + CLI) is the entry point to a Hyvä migration quote. For client work we follow this sequence:

  1. Grep + CLI every third-party module on the existing Magento 2.4.4 — 2.4.9 store. Catalog the results: green (compatible), yellow (needs minor port), red (needs full rewrite or replacement).
  2. Replace red modules with Hyvä-native equivalents from hyva.io's compat module list[2]. The community ships ~250 vetted Hyvä-compatible modules.
  3. Port yellow modules by writing Magewire components or Alpine.js handlers against the same backend API. Most yellows take 8–16 hours each.
  4. Smoke-test the storefront with all green/ported modules installed on a Hyvä staging site, in incognito, with DevTools console open.
  5. Run Lighthouse mobile on the staging site — a properly Hyvä-compatible build should hit performance 85+ on mobile.

FAQ

Can I run the CLI against a module I have not installed yet?

Not directly — the CLI walks the module via Magento's module registry, so the module needs to be present in vendor/ and registered (not necessarily enabled). For pre-install audits, manual grep against the unzipped source is the right approach.

What about Magewire-specific modules — does the CLI flag those?

The CLI does not check whether your storefront has Magewire installed. A module that depends on Magewire will pass the CLI scan and then fail on a vanilla Hyvä site because magewirephp/magewire is not in composer.json. The fix is a manual review of the module's composer.json for Magewire as a requirement.

Is there a CI-friendly mode?

Yes — pass --format=json for machine-readable output, and the command exit code is non-zero if any INCOMPATIBLE issues are found. Plumb that into your GitHub Actions or Bitbucket Pipelines pre-merge check to keep Luma-only modules from landing on a Hyvä-bound branch.

Does it audit admin and email surfaces?

No. The CLI is frontend-storefront only. Admin UI components, email templates, and PDF rendering are out of scope. Those surfaces are nearly always Hyvä-compatible by default because Hyvä replaces the storefront only.

What is the typical effort to port a Luma-only checkout extension?

From our last 8 ports: 12 — 24 hours for a single-field extension (one Magewire component, two templates, one layout XML, two PHP observers). Doubles if the extension ships a custom REST endpoint that needs Hyvä's CSRF flow.

How often should we re-audit?

Re-audit every minor Hyvä Themes release (roughly quarterly) and every Magento 2.4.x release.

Sources

  1. hyva-themes/magento2-compatibility-checker — GitHub repository and README
  2. hyva.io — Hyvä-compatible extension directory
Need a Hyvä compatibility audit for your extension stack?

I run grep + CLI + manual review across the full vendor tree and ship a colour-coded migration plan (green/yellow/red) with per-module effort estimates. Fixed quote from $499 audit · $2,499 sprint · ~20h @ $25/hr. See /hire-me.