← Voltar ao blog

Hyvä vs Luma em 2026: o que muda para o desenvolvedor Magento

Rodrigo Biazzi

A maioria dos projetos novos de frontend Magento 2 hoje começa com uma escolha entre a stack Luma, que vem com o Magento, e o Hyvä. As comparações costumam focar nas notas do Lighthouse. Esta é sobre o trabalho do dia a dia: o que o desenvolvedor escreve, depura e mantém em cada stack, e o que isso significa para extensões, checkout e orçamentos.

Duas stacks de frontend bem diferentes

O Luma, e o seu pai Blank, é o frontend com o qual o Magento 2 vem desde o início. Ele é construído sobre:

  • RequireJS para carregar módulos JavaScript
  • jQuery e widgets do jQuery UI
  • KnockoutJS e UI components para as partes dinâmicas, incluindo o mini cart e o checkout inteiro
  • LESS compilado pelo static content deployment do Magento

O Hyvä substitui tudo isso na storefront. Um tema Hyvä usa:

  • Alpine.js para interatividade, escrito inline nos templates
  • Tailwind CSS, compilado com uma etapa de build em Node dentro do tema
  • Nada de RequireJS, jQuery ou Knockout na storefront
  • O mesmo backend do Magento: layout XML, blocks, view models, templates PHP e customer data sections continuam valendo

O último ponto importa. O Hyvä não é uma abordagem headless ou PWA. É um tema Magento normal que renderiza HTML no servidor. Tudo o que você sabe sobre layout handles, blocks, plugins e cache continua valendo. O que muda é a camada de JavaScript e CSS, e com ela quanto código roda no navegador.

Escrevendo um componente em cada stack

Luma: um widget JavaScript ou UI component

No Luma, um pequeno elemento interativo costuma significar um template, um arquivo JavaScript registrado como módulo RequireJS e uma tag script x-magento-init para ligar os dois.

<div class="stock-alert" data-mage-init='{"Acme_StockAlert/js/stock-alert": {"productId": <?= (int) $block->getProductId() ?>, "url": "<?= $escaper->escapeUrl($block->getUrl('stockalert/subscribe')) ?>"}}'>
    <button type="button" class="action primary"><?= $escaper->escapeHtml(__('Notify me')) ?></button>
</div>
define(['jquery', 'mage/cookies'], function ($) {
    'use strict';

    return function (config, element) {
        $(element).on('click', 'button', function () {
            $.post(config.url, {product: config.productId, form_key: $.mage.cookies.get('form_key')});
        });
    };
});

Alterar um comportamento existente no Luma muitas vezes significa um mixin do RequireJS, declarado no requirejs-config.js:

var config = {
    config: {
        mixins: {
            'Magento_Checkout/js/action/place-order': {
                'Acme_Checkout/js/action/place-order-mixin': true
            }
        }
    }
};

Mixins são poderosos, mas rastrear qual arquivo envolve qual módulo em dezenas de extensões é um trabalho lento, e o static content deployment precisa rodar antes de você ver uma mudança em modo production.

Hyvä: Alpine.js no template

No Hyvä a mesma feature vive em um único template. Estado e comportamento ficam ao lado do markup.

<?php
/** @var \Magento\Framework\View\Element\Template $block */
/** @var \Magento\Framework\Escaper $escaper */
$productId = (int) $block->getData('product_id');
?>
<div x-data="initStockAlert()">
    <button type="button" class="btn btn-primary" x-on:click="subscribe()" x-bind:disabled="sent">
        <?= $escaper->escapeHtml(__('Notify me')) ?>
    </button>
    <p x-show="sent" x-cloak><?= $escaper->escapeHtml(__('We will email you.')) ?></p>
</div>
<script>
    function initStockAlert() {
        return {
            sent: false,
            subscribe() {
                fetch('<?= $escaper->escapeJs($block->getUrl('stockalert/subscribe')) ?>', {
                    method: 'POST',
                    headers: {'Content-Type': 'application/x-www-form-urlencoded'},
                    body: new URLSearchParams({
                        product: '<?= $productId ?>',
                        form_key: hyva.getFormKey()
                    })
                }).then(() => { this.sent = true; });
            }
        };
    }
</script>

Não há etapa de build para o JavaScript e nada para registrar. As classes do Tailwind precisam do build de CSS, que pega as classes dos seus templates. Para a maioria dos desenvolvedores que conhecem PHP e um pouco de JavaScript moderno, isso é mais rápido de ler e de alterar do que o equivalente no Luma.

Conteúdo privado

As customer data sections funcionam igual no lado do servidor. No cliente, o Hyvä dispara um evento private-content-loaded no window quando os dados da section estão prontos, e os componentes escutam esse evento:

<div x-data="{ cartCount: 0 }"
     x-on:private-content-loaded.window="cartCount = $event.detail.data.cart ? $event.detail.data.cart.summary_count : 0">
    <span x-text="cartCount"></span>
</div>

Isso quer dizer que a sua estratégia de full page cache continua a mesma. As páginas ainda são cacheadas como HTML compartilhado e os dados pessoais ainda são carregados de customer/section/load.

Estilização: LESS versus Tailwind

Estilizar no Luma significa sobrescrever variáveis e mixins do LESS do Magento_Theme e dos arquivos web/css/source de cada módulo, herdando do Blank ou do Luma. Mudanças pequenas são fáceis. Redesigns grandes acabam brigando com a especificidade do tema pai e você entrega muito CSS que nunca usa.

No Hyvä você estiliza com classes utilitárias nos templates e configura os design tokens na configuração do Tailwind dentro da pasta web/tailwind do tema. O build escaneia os templates atrás de classes e só gera o que é usado, então o CSS fica pequeno. O trade-off é que mudanças de design significam editar templates, e um desenvolvedor que nunca usou Tailwind precisa de um tempo para se sentir à vontade.

Um child theme do Hyvä declara o pai no theme.xml como qualquer tema Magento:

<theme xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:noNamespaceSchemaLocation="urn:magento:framework:Config/etc/theme.xsd">
    <title>Acme Store</title>
    <parent>Hyva/default</parent>
</theme>

View models e o registry do Hyvä

O Hyvä incentiva view models em vez de classes de block. Além de passá-los como argumentos de layout, todo template do Hyvä recebe uma variável $viewModels, uma instância de Hyva\Theme\Model\ViewModelRegistry, que permite ao template pedir qualquer view model diretamente:

<?php
/** @var \Hyva\Theme\Model\ViewModelRegistry $viewModels */
$heroicons = $viewModels->require(\Hyva\Theme\ViewModel\HeroiconsOutline::class);
?>
<?= $heroicons->shoppingCartHtml('w-6 h-6') ?>

É conveniente e remove muito layout XML. Use com cuidado em templates compartilhados amplamente, porque as dependências ficam menos visíveis do que em argumentos de layout.

Extensões: o custo real

É aqui que vai a maior parte do tempo de planejamento. Qualquer extensão Magento com JavaScript de frontend escrito para o Luma (RequireJS, jQuery, Knockout) não vai funcionar em uma storefront Hyvä do jeito que está. A parte de backend da extensão funciona, mas o frontend dela precisa de uma versão para o Hyvä.

As opções para cada extensão são:

  • O fornecedor já entrega suporte a Hyvä, embutido ou como um pacote separado.
  • Existe um módulo de compatibilidade no tracker de módulos de compatibilidade do Hyvä ou na comunidade.
  • Você escreve o módulo de compatibilidade: templates novos com Alpine.js, às vezes layout XML novo, reaproveitando o backend da extensão.
  • A página que precisa da extensão cai para o Luma, pelo fallback do tema Luma do Hyvä para rotas específicas.

Antes de se comprometer com o Hyvä, liste toda extensão com saída de frontend e confira cada uma. Extensões que só mexem no admin, em APIs, no cron ou no banco de dados não são afetadas de forma alguma. Em uma loja com muitas extensões de frontend, o trabalho de compatibilidade pode ser maior do que o do próprio tema.

Checkout

O checkout do Luma é uma single page application em Knockout construída com UI components e configurada pelo layout checkout_index_index.xml e por JavaScript. Customizá-lo significa layout processors, mixins e templates Knockout. Muitas extensões de pagamento e envio trazem código exatamente para esse checkout.

Em uma loja Hyvä você tem dois caminhos principais:

  • Fallback para o checkout Luma. O checkout continua usando a stack Luma enquanto o resto da loja roda no Hyvä. As extensões de pagamento funcionam como hoje. Você ainda mantém a estilização Luma das páginas de checkout.
  • Hyvä Checkout. Um produto comercial separado do Hyvä, construído sobre o Magewire, uma biblioteca de componentes dirigida pelo servidor. As customizações são escritas principalmente em PHP e templates. Métodos de pagamento e envio precisam de suporte ao Hyvä Checkout dos seus fornecedores ou de um módulo de compatibilidade.

O licenciamento e o preço do tema Hyvä e dos seus produtos comerciais mudaram com o tempo, então confira os termos atuais no site do Hyvä antes de estimar um projeto.

Debugging e ferramentas

  • No Luma, bugs de frontend muitas vezes estão na interação entre módulos RequireJS, mixins e bindings do Knockout. As dev tools do navegador e os source maps ajudam, mas o static content deployment e o cache do pub/static são fontes frequentes de confusão. Na dúvida, limpe o pub/static/frontend e o var/view_preprocessed em uma máquina de desenvolvimento.
  • No Hyvä, a maior parte do comportamento está visível no template que o renderiza. As dev tools do Alpine.js para o navegador mostram o estado dos componentes. O problema comum é uma classe do Tailwind que não aparece no CSS porque o build não escaneou o arquivo que a usa, então confira primeiro os content paths na configuração do Tailwind.

As duas stacks usam as mesmas ferramentas de backend: debug de layout, template hints (bin/magento dev:template-hints:enable), o profiler e os comandos de cache.

Qual escolher

Para um projeto novo ou um redesign completo, o Hyvä costuma ser o padrão mais forte, desde que a lista de extensões tenha sido verificada e o caminho do checkout esteja decidido. A storefront é mais leve, as mudanças de frontend são mais rápidas de fazer e o código é mais fácil de acompanhar para desenvolvedores novos.

O Luma ainda faz sentido quando a loja depende muito de extensões sem suporte a Hyvä, quando não há orçamento para reconstruir o frontend e o tema atual funciona, ou quando a equipe tem muita experiência com Knockout e UI components e não tem tempo para aprender uma stack nova. A performance dele também pode ser melhorada, com bundling de JavaScript cuidadoso, menos extensões na storefront e cache bem feito, embora não chegue ao mesmo patamar de base do Hyvä.

Seja qual for a sua escolha, as habilidades de backend são as mesmas. Layout XML, view models, plugins, service contracts e full page cache funcionam nos dois, e é aí que mora a maior parte do conhecimento específico de Magento.

FAQ

O Hyvä é um frontend headless ou PWA?

Não. O Hyvä é um tema Magento normal renderizado no servidor. Layout XML, blocks, view models e full page cache funcionam como de costume. Ele substitui a camada de RequireJS, jQuery, Knockout e LESS por Alpine.js e Tailwind CSS.

Extensões do Luma funcionam em uma loja Hyvä?

As partes de backend delas funcionam. As partes de frontend construídas em RequireJS, jQuery ou Knockout precisam de uma versão compatível com o Hyvä, de um módulo de compatibilidade ou de um fallback Luma para as páginas que as usam.

Posso usar o checkout padrão do Magento com o Hyvä?

Sim. O checkout Luma pode ser mantido por um fallback enquanto o resto da loja usa Hyvä. A alternativa é o Hyvä Checkout, um produto separado construído sobre o Magewire.

Preciso de Node.js para trabalhar em um tema Hyvä?

Sim, para o build do Tailwind CSS dentro da pasta web/tailwind do tema. Os componentes Alpine.js em si são escritos nos templates e não precisam de etapa de build.

Atendo como freelancer em Magento e Adobe Commerce, de desenvolvimento de módulos e auditorias de performance a migrações e projetos com Hyvä. Se isso for útil, fale comigo.

Artigos relacionados