DEV Community

Magevanta
Magevanta

Posted on • Originally published at magevanta.com

Hyvä Theme Performance: Why You Should Ditch Luma in 2026

If you're still running a Luma-based theme on your Magento 2 store in 2026, you're leaving significant performance on the table. The Hyvä theme has matured into the de-facto frontend standard for Magento developers who care about speed, maintainability, and Core Web Vitals. This guide explains exactly why, with numbers to back it up.

The Problem with Luma

Luma shipped with Magento 2.0 in 2015. It was designed for an era before Lighthouse scores, INP metrics, or the performance bar Google sets today. Under the hood, Luma relies on:

  • RequireJS for module loading — hundreds of individual JS requests (or a slow bundled blob)
  • KnockoutJS for UI components — a heavy runtime that initialises on every page
  • jQuery and dozens of jQuery plugins
  • CSS compiled from deep LESS inheritance chains

The result? A typical Luma homepage ships with 400–600 KB of JavaScript that must parse and execute before anything interactive works. On a fast connection and a desktop Chrome, this is tolerable. On mobile — which accounts for 60%+ of e-commerce traffic — it's a conversion killer.

Typical Lighthouse scores for a reasonably optimised Luma store:

  • Performance: 40–60 (mobile)
  • LCP: 4–7 seconds
  • TBT (Total Blocking Time): 1,500–3,000 ms

What Hyvä Does Differently

Hyvä, built by Willem Wigman and the community around it, throws out the RequireJS/KnockoutJS stack entirely and replaces it with two modern, lightweight tools:

  • Alpine.js — ~15 KB gzipped, declarative, zero build step for simple interactions
  • Tailwind CSS — utility-first, purged to only the classes you actually use (typically 10–30 KB)

No RequireJS. No KnockoutJS. No jQuery (unless a third-party module forces it). The JavaScript bundle shrinks from 400+ KB to under 40 KB in a clean Hyvä setup.

Core Architecture Differences

Feature Luma Hyvä
JS Framework KnockoutJS + RequireJS Alpine.js
CSS LESS (compiled) Tailwind CSS (purged)
JS bundle size ~400–600 KB ~30–50 KB
CSS size ~200–400 KB ~10–30 KB
Component system XML layout + phtml + JS mixins phtml + Alpine data attributes
Build tooling Grunt / bin/magento setup:static-content:deploy Vite (optional) + Tailwind CLI

Real-World Performance Numbers

Community benchmarks and case studies consistently show the same pattern. Here's what you can expect after a Hyvä migration on a mid-size Magento store:

Mobile Lighthouse (representative averages):

  • Performance score: 75–95 (up from 40–60)
  • LCP: 1.5–2.5 s (down from 4–7 s)
  • TBT: 100–300 ms (down from 1,500–3,000 ms)
  • CLS: < 0.05 (Hyvä's server-rendered approach avoids layout shift)

These aren't cherry-picked numbers. They're the range you see across e-commerce blogs, Hyvä's own case studies, and agencies that have done dozens of migrations.

Google's Core Web Vitals directly influence organic ranking. Improving your mobile LCP from 5 seconds to 2 seconds is not just a UX win — it's an SEO win.

Static Content Deploy: A Hidden Bonus

One pain that every Magento 2 team lives with is setup:static-content:deploy. On a Luma store with multiple themes and locales, this command can take 10–20 minutes. This blocks deployment pipelines, makes hotfixes painful, and slows CI/CD cycles.

Hyvä's CSS is generated by Tailwind's CLI in under 10 seconds, even for large stores. The JS doesn't need RequireJS bundling at all. Your total static asset build time drops dramatically.

For teams using zero-downtime deployment strategies (Blue/Green, symlink swaps), this shorter build time means less risk and faster rollbacks.

What About Third-Party Extensions?

This is the real question every merchant asks. Most Magento 2 extensions ship with Luma frontend components. When you switch to Hyvä, those KnockoutJS/RequireJS components simply don't exist.

The Hyvä ecosystem has addressed this through the Hyvä Compatibility Layer (a paid add-on module) which allows Luma UI components to run inside a Hyvä page as an iframe fallback. It's not pretty, but it works as a bridge.

More importantly: the major extensions — Amasty, Mageworx, Mollie, Klarna, Stripe, Yotpo, and many others — now ship dedicated Hyvä compatibility modules, either bundled or via the Hyvä Marketplace. Before migrating, audit your extension stack:

# List all installed third-party modules
bin/magento module:status | grep -v "Magento_"
Enter fullscreen mode Exit fullscreen mode

For each module, check:

  1. Does it have a Hyvä-compatible module on the Hyvä Marketplace?
  2. Does the vendor provide their own Hyvä support?
  3. Can the functionality be replaced with a Hyvä-native extension?

Migration Strategy

Option 1: Full Migration (Greenfield)

Best for stores that are redesigning anyway or have simple extension stacks. You build a new Hyvä theme from scratch, implement all frontend templates in phtml + Alpine, and migrate one page type at a time.

Timeline: 4–12 weeks depending on store complexity.

Option 2: Progressive Migration

Start with Hyvä as the base theme but keep Luma fallback for complex checkout or account pages using the compatibility layer. Migrate page types incrementally.

Timeline: 2–4 weeks for initial launch, then ongoing.

Option 3: Hyvä + React Checkout

Pairing Hyvä with a React-based checkout (Checkout Suite, Hyva Checkout, or React Checkout for Magento) gives you maximum flexibility for the most performance-critical page. Many agencies now recommend this as the default stack.

Setting Up a Basic Hyvä Theme

Hyvä is a paid theme (one-time license ~€1,000 for the base theme). After purchase you get access to the private Composer repository.

# Add Hyvä repo to your composer.json
composer config repositories.hyva-themes composer https://hyva-themes.gitlab.io/magento2-hyva-compat/packages.json

# Install
composer require hyva-themes/magento2-default-theme

# Create your child theme
bin/magento hyva:config:generate
Enter fullscreen mode Exit fullscreen mode

Your child theme lives in app/design/frontend/YourVendor/YourTheme/ and follows standard Magento theme inheritance. You override only the templates you need; everything else inherits from the default Hyvä theme.

<!-- theme.xml -->
<theme xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:noNamespaceSchemaLocation="urn:magento:framework:Config/etc/theme.xsd">
    <title>Your Store Theme</title>
    <parent>Hyva/default</parent>
</theme>
Enter fullscreen mode Exit fullscreen mode

Tailwind Configuration for Magento

Hyvä ships with a tailwind.config.js that scans your phtml files for class names:

// tailwind.config.js
module.exports = {
  content: [
    './src/**/*.phtml',
    './src/**/*.html',
    // Include Hyvä default theme templates too
    '../../vendor/hyva-themes/magento2-default-theme/Magento_Theme/templates/**/*.phtml',
  ],
  theme: {
    extend: {
      colors: {
        primary: {
          lighter: '#f0f9ff',
          DEFAULT: '#0ea5e9',
          darker: '#0369a1',
        },
      },
    },
  },
}
Enter fullscreen mode Exit fullscreen mode

Build your CSS:

# Development (watch mode)
npx tailwindcss -i ./src/css/styles.css -o ./web/css/styles.css --watch

# Production (minified + purged)
NODE_ENV=production npx tailwindcss -i ./src/css/styles.css -o ./web/css/styles.css --minify
Enter fullscreen mode Exit fullscreen mode

Alpine.js Components in Hyvä

Hyvä uses Alpine.js for interactive components. Here's a simple example — a custom product quantity selector:

<div x-data="{ qty: 1, min: 1, max: 100 }" class="flex items-center gap-2">
    <button
        type="button"
        class="w-8 h-8 border rounded"
        @click="qty = Math.max(min, qty - 1)"
        :disabled="qty <= min"
    ></button>

    <input
        type="number"
        x-model.number="qty"
        :min="min"
        :max="max"
        class="w-16 text-center border rounded"
    />

    <button
        type="button"
        class="w-8 h-8 border rounded"
        @click="qty = Math.min(max, qty + 1)"
        :disabled="qty >= max"
    >+</button>
</div>
Enter fullscreen mode Exit fullscreen mode

No KnockoutJS data-bind syntax. No RequireJS define(). Just HTML attributes that any developer can read and understand immediately.

Should You Migrate?

If your store is under active development and you're planning a redesign, yes, migrate to Hyvä. The performance gains are real, the developer experience is dramatically better, and the community has reached critical mass.

If you're running a stable store with no upcoming redesign and 20+ complex extensions, a migration needs careful planning. The ROI is there — better Core Web Vitals, faster deploys, happier developers — but the effort is real.

As a rule of thumb: any new Magento 2 project in 2026 should start with Hyvä by default. Luma is legacy.

Resources

The frontend world has moved on from 2015-era JavaScript frameworks. Hyvä is how Magento 2 keeps up.

Top comments (0)