Skip to content

Updating to Venta Theme 1.6.0 (TailwindCSS v4)

This release upgrades the build stack from TailwindCSS v3 (PostCSS, tailwind.config.js) to TailwindCSS v4 (CSS-first @theme, standalone CLI, no PostCSS). The amount of automated and manual migration work is significant. Following the steps in this order keeps the process as smooth as possible — most class renames and CSS rewrites are handled by tools, so do those first and reconcile manual overrides last.

Recommended reading — skim for general orientation before starting:

Prerequisites

  • Node.js 20 or higher (required by Hyvä).
  • Browser support: TailwindCSS v4 targets modern browsers (Safari 16.4+, Chrome 111+, Firefox 128+). If the project must support older clients, stay on v3.

1. Update Venta Theme via Composer

Update Venta Theme, all Venta Theme modules, and their dependencies via Composer.

TIP

At this step, do not reconcile manually overridden files. This release contains a large number of utility class changes. Many of those are handled automatically by the upgrade tools covered in §2§4, so updating overrides now only adds friction. If the storefront is breaking before you reach those steps, unblock the critical failures first — then continue with the guide.

Install the Hyvä Upgrade Helper

The upgrade process uses hyva-themes/upgrade-helper-tools.

Install it via Composer:

bash
composer require hyva-themes/upgrade-helper-tools --dev

WARNING

Not all Hyvä licence tiers include access to the upgrade-helper-tools repository. If Composer reports that the package does not exist or returns an authentication error, your licence tier likely does not include access to this repository. Contact Hyvä support to verify your licence, or use the copy-from-default-theme path as a fallback.

2. Upgrade the TailwindCSS Directory

Run the upgrade tool

From the Magento root, run the conversion script (replace {ProjectTheme} with your theme directory name):

bash
vendor/hyva-themes/upgrade-helper-tools/bin/convert-to-tailwind-v4.js app/design/frontend/Magebit/{ProjectTheme}

The tool does two things:

  1. Creates a new tailwind/ directory with the TailwindCSS v4 folder structure.
  2. Creates a tailwind.backup.<timestamp>/ directory containing your previous setup.

Do not delete the backup yet — you will restore your custom stylesheets from it in §3.

Restore npm dependencies

The upgrade tool modifies package.json and may strip devDependencies. Restore everything before continuing.

Install the updated core packages:

bash
npm install @hyva-themes/hyva-modules@latest
npm install tailwindcss@latest
npm install @tailwindcss/cli@latest

Restore devDependencies:

bash
npm install --save-dev esbuild stylelint stylelint-config-standard stylelint-config-tailwindcss

Add a .stylelintrc.json file to the web/tailwind/ directory:

json
{
  "extends": [
    "stylelint-config-standard",
    "stylelint-config-tailwindcss"
  ],
  "customSyntax": "postcss",
  "rules": {
    "selector-class-pattern": null,
    "media-query-no-invalid": null
  }
}

The upgrade tool also removes stylelint, stylelint-fix, and build-prod scripts from package.json. Restore the full scripts block:

json
"scripts": {
  "start": "npm run watch",
  "generate": "npx hyva-sources && npx hyva-tokens",
  "prewatch": "npm run generate",
  "watch": "npx tailwindcss -i tailwind-source.css -o ../css/styles.css --watch",
  "browser-sync": "npx browser-sync start --config ./browser-sync.config.js",
  "prebuild": "npm run generate",
  "build": "npx tailwindcss -i tailwind-source.css -o ../css/styles.css --minify",
  "stylelint": "npx stylelint --allow-empty-input \"**/*.css\" \"../../../../../../../app/code/Magebit/**/*.css\" \"!tailwind-source.css\" \"!generated/**\"",
  "stylelint-fix": "npx stylelint --allow-empty-input --fix \"**/*.css\" \"../../../../../../../app/code/Magebit/**/*.css\" \"!tailwind-source.css\" \"!generated/**\""
}

WARNING

The generated/ exclusions in the stylelint scripts are required. The files under generated/ are auto-generated and will produce a flood of false lint errors without them.

INFO

Adjust the app/code/Magebit/**/*.css glob to match your actual vendor namespace.

Clean the generated Hyvä layers

When the upgrade tool creates the new tailwind/ structure it populates base/, components/, and theme/ with Hyvä Theme's own stylesheets. On a Venta Theme stack these are redundant — Venta Theme's own layers rewrite them entirely. Leaving both in place creates a redundant rewrite cycle: Hyvä Theme's styles are compiled, then immediately overwritten by Venta Theme's equivalents, leading to bloated output and potential specificity inconsistencies.

Delete the contents of base/, components/, and theme/ (or utilities/ if present). Leave an empty index.css placeholder in each folder, or delete the folder entirely if you have no custom styles for that layer:

tailwind/
  base/
    index.css       ← leave as empty placeholder; delete the folder entirely if you have no custom styles for this layer
  components/
    index.css       ← leave as empty placeholder; delete the folder entirely if you have no custom styles for this layer
  theme/
    index.css       ← leave as empty placeholder; delete the folder entirely if you have no custom styles for this layer
  utilities/
    index.css       ← leave as empty placeholder; delete the folder entirely if you have no custom styles for this layer

Your custom partials will be placed back here in §3.

Replace tailwind-source.css

Replace the entire contents of web/tailwind/tailwind-source.css with the following. Import order is critical: Hyvä modules first, then TailwindCSS with source(none), then Venta Theme layers, then generated files, then your project overrides last so they win by source order.

css
/**
 * @copyright Copyright (c) 2026 Magebit, Ltd. (https://magebit.com/)
 * @author Magebit <info@magebit.com>
 * @license MIT
 */

@import "@hyva-themes/hyva-modules/css";
@import "tailwindcss" source(none);
@source "../../**/*.phtml";
@source "../../**/*.xml";

/* Venta Theme variables */
@import "../../../../../../../vendor/magebitcom/magento2-venta-theme/web/tailwind/theme.css";

/* Venta Theme Base Layer */
@import "../../../../../../../vendor/magebitcom/magento2-venta-theme/web/tailwind/base/index.css";

/* Venta Theme Components */
@import "../../../../../../../vendor/magebitcom/magento2-venta-theme/web/tailwind/components/index.css";

/* Venta Theme Utilities */
@import "../../../../../../../vendor/magebitcom/magento2-venta-theme/web/tailwind/utilities/index.css";

/* Generated styles for Hyvä-compatible modules and design tokens */
@import "./generated/hyva-source.css";
@import "./generated/hyva-tokens.css";

/* Venta Theme global theme layer (theme-scoped styles, e.g. body, headings) */
@import "../../../../../../../vendor/magebitcom/magento2-venta-theme/web/tailwind/theme/index.css";

/* Project custom variables — imported after Venta Theme to correctly override */
/* theme.css is optional; replace this import with an inline @theme {} block in tailwind-source.css if preferred */
@import "./{ProjectTheme}-variables.css";

/* Project custom styles — imported last to override everything by source order */
@import "./base";
@import "./components";
@import "./utilities";
@import "./theme";

INFO

TailwindCSS v4 requires the ./ prefix on relative @import paths. @import "base" without ./ will not resolve correctly.

TIP

If the project has a Child Theme that extends main Project Theme, it needs its own tailwind-source.css with an additional @import layer pointing back to Project Theme's compiled layers. Each level in the Hyvä → Venta Theme → {ProjectTheme} → {ProjectChildTheme} hierarchy manages its own tailwind-source.css.

Example: multi-level hierarchy (Venta Theme → ProjectTheme → ProjectChildTheme)
css
/**
 * @copyright Copyright (c) 2026 Magebit, Ltd. (https://magebit.com/)
 * @author Magebit <info@magebit.com>
 * @license MIT
 */

@import "@hyva-themes/hyva-modules/css";
@import "tailwindcss" source(none);
@source "../../**/*.phtml";
@source "../../**/*.xml";

/* Venta Theme variables */
@import "../../../../../../../vendor/magebitcom/magento2-venta-theme/web/tailwind/theme.css";

/* Venta Theme Base Layer */
@import "../../../../../../../vendor/magebitcom/magento2-venta-theme/web/tailwind/base/index.css";

/* Venta Theme Components */
@import "../../../../../../../vendor/magebitcom/magento2-venta-theme/web/tailwind/components/index.css";

/* Venta Theme Utilities */
@import "../../../../../../../vendor/magebitcom/magento2-venta-theme/web/tailwind/utilities/index.css";

/* Generated styles for Hyvä-compatible modules and design tokens */
@import "./generated/hyva-source.css";
@import "./generated/hyva-tokens.css";

/* Venta Theme global theme layer (theme-scoped styles, e.g. body, headings) */
@import "../../../../../../../vendor/magebitcom/magento2-venta-theme/web/tailwind/theme/index.css";

/*
 * Hierarchy: Venta Theme → {ProjectTheme} → {ProjectChildTheme} (this file)
 * Each layer overrides the previous by CSS source order.
 * 1. {ProjectTheme} design tokens (colors, spacing, fonts, etc.)
 * 2. {ProjectTheme} custom layers (base, components, utilities, theme)
 * 3. {ProjectChildTheme} design token overrides
 * 4. {ProjectChildTheme} custom layers
 */

/* {ProjectTheme} design tokens */
@import "../../../{ProjectTheme}/web/tailwind/{ProjectTheme}-variables.css";

/* {ProjectTheme} custom layers */
@import "../../../{ProjectTheme}/web/tailwind/base";
@import "../../../{ProjectTheme}/web/tailwind/components";
@import "../../../{ProjectTheme}/web/tailwind/utilities";
@import "../../../{ProjectTheme}/web/tailwind/theme";

/* {ProjectChildTheme} design token overrides */
@import "./{ProjectChildTheme}-variables.css";

/* {ProjectChildTheme} custom layers */
@import "./base";
@import "./components";
@import "./utilities";
@import "./theme";

INFO

For highly customized projects where appending styles after Venta Theme's layers is not enough, see §3 — Advanced: Venta Theme layer proxy override.

Configure hyva.config.json

hyva.config.json lives in web/tailwind/ and is auto-generated by the upgrade tool. If it is missing, generate it with npx hyva-init (docs). It controls two things: which paths are scanned for TailwindCSS class names (via npx hyva-sources) and which design tokens are generated (via npx hyva-tokens).

Two discovery mechanisms — understand the difference before editing:

  1. app/etc/hyva-themes.json — auto-generated by Magento (bin/magento setup:upgrade / bin/magento hyva:config:generate). Every Hyvä-compatible module registers itself here. Do not add these paths to hyva.config.json.
  2. hyva.config.jsontailwind.include — use this only for paths not in hyva-themes.json.

All paths in include are relative to the Magento root (no leading /). After any change, run:

bash
npm run generate

What to add to tailwind.include:

PathWhy
vendor/hyva-themes/magento2-default-themeHyvä Default Theme templates; not in hyva-themes.json
vendor/magebitcom/magento2-venta-themeVenta Theme base; not in hyva-themes.json
app/codeCustom module templates in app/code/; not covered by @source "../../**/*.phtml" which only scans the theme directory

What not to add: do not add modules already listed in app/etc/hyva-themes.json. They already receive a @source entry from npx hyva-sources — adding them again only duplicates the scan. All Magebit modules ship with built-in Hyvä compatibility registration, so they self-register into hyva-themes.json automatically after bin/magento setup:upgrade. Before editing hyva.config.json, check the current contents of app/etc/hyva-themes.json to confirm which paths are already covered.

Example hyva.config.json for Project Theme (direct Venta Theme child):

json
{
  "tailwind": {
    "include": [
      { "src": "vendor/hyva-themes/magento2-default-theme" },
      { "src": "vendor/magebitcom/magento2-venta-theme" },
      { "src": "app/code" }
    ],
    "exclude": [
      { "src": "vendor/hyva-themes/magento2-hyva-checkout/src", "keepSource": true }
    ]
  }
}
Multi-level hierarchy (Venta Theme → {ProjectTheme} → {ProjectChildTheme})

Add Project Theme to include so its templates are also scanned for TailwindCSS class names:

json
{
  "tailwind": {
    "include": [
      { "src": "vendor/hyva-themes/magento2-default-theme" },
      { "src": "vendor/magebitcom/magento2-venta-theme" },
      { "src": "app/design/frontend/Magebit/{ProjectTheme}" },
      { "src": "app/code" }
    ],
    "exclude": [
      { "src": "vendor/hyva-themes/magento2-hyva-checkout/src", "keepSource": true }
    ]
  }
}

WARNING

Hyvä Checkout CSS conflict: If the project uses Venta Theme checkout layout, exclude vendor/hyva-themes/magento2-hyva-checkout/src. Hyvä Checkout's module.css contains TailwindCSS component definitions and CSS specificity conflicts that make the checkout render inconsistently when combined with Venta Theme checkout styles.

There is currently no clean way to replace individual files inside a generated source import without bloating the final styles.css. The only reliable option is to exclude the source entirely. If you still need Hyvä Checkout templates to contribute class names to the TailwindCSS scan (e.g. you are only partially overriding), add "keepSource": true:

json
{ "src": "vendor/hyva-themes/magento2-hyva-checkout/src", "keepSource": true }

See Hyvä — Excluding modules.

Further reading:

3. CSS Custom Styles Migration

This section covers migrating your custom CSS from the v3 backup into the new v4 structure. It is the most involved manual step — take it methodically.

Restore custom stylesheets from backup

Open the tailwind.backup.<timestamp>/ folder created by the upgrade tool. Copy your custom partial CSS files back into the corresponding folders in the new tailwind/ directory:

  • Custom base styles → tailwind/base/
  • Custom component styles → tailwind/components/
  • Custom utility styles → tailwind/utilities/
  • Custom theme styles → tailwind/theme/

Do not copy Hyvä Theme's original files — those belong to the default theme and are not needed on Venta Theme.

Add index.css entry files

Each folder that contains partials needs an index.css that imports them. Create or update it for every folder you restored files into:

css
/* tailwind/components/index.css */
@import "./blog.css";
@import "./fontfamily.css";
@import "./hero.css";

tailwind-source.css imports these folders by directory path (e.g. @import "./components"), which resolves to components/index.css.

Migrate tailwind.browser-jit-config.js@theme

tailwind.browser-jit-config.js is no longer read by TailwindCSS v4 and has no effect on compilation. Every custom token defined there must be rewritten as a CSS variable inside an @theme {} block.

Place your project's @theme {} block after all Venta Theme imports in tailwind-source.css (or in a dedicated ./theme.css that is already imported there). This guarantees your values override Venta Theme's defaults by source order.

Example:

css
/* theme.css or inside tailwind-source.css after Venta Theme imports */
@theme {
  --font-sans: "Lato", "LatoFallback", "Arial", sans-serif;
  --color-primary: var(--color-primary-500);
  --color-primary-500: #203340;
  --color-accent: #d4a853;
}

Variable naming rules (kebab-case)

v4 theme variables use kebab-case. Avoid capitals, dots, slashes, and % signs in variable names — encode them as shown:

v3 theme.extend keyv4 @theme variable
fontFamily.sans--font-sans
colors.primary.500--color-primary-500
colors.primary.DEFAULT--color-primary
colors.accent.light--color-accent-light
maxWidth['mobile-logo']--width-mobile-logo
minWidth['product-list-mobile']--min-width-product-list-mobile
spacing['45']--spacing-45
spacing['71.5']--spacing-71-5 (.-)
spacing['84%']--spacing-84-pct (%-pct)
inset['1/10']--inset-10pct (/ and fraction → identifier)
aspectRatio['home-hero-banner']--aspect-ratio-home-hero-banner
backgroundImage['category-list-widget']--background-image-category-list-widget
gridTemplateColumns['3columns-blog']--grid-template-columns-3columns-blog

Semantic tokens follow the same convention (these names are what Venta Theme uses — keep them consistent for overrides to work):

  • --color-button-primary-hover
  • --color-button-secondary-hover
  • --color-button-link-hover
  • --color-button-link-active
  • --color-link-hover
  • --color-input-border-focus
  • --color-input-border-search-hover
  • --color-border-darker

Replace theme() dot notation with var() and theme(--var)

In v4, theme() dot notation is removed for use in regular CSS properties. Use CSS variables directly instead.

v3:

css
.selector {
  background-color: theme(colors.primary.500);
}

v4:

css
.selector {
  background-color: var(--color-primary-500);
}

The only place theme() is still used in v4 is inside @media queries, where it must reference the variable name:

css
@media (width >= theme(--breakpoint-xl)) { ... }

Replace @screen with @media

@screen is removed in v4. Replace every occurrence with a standard @media query using theme(--breakpoint-*).

v3:

css
@screen xl {
  .mpblog-post-view {
    &.page-layout-2columns-left,
    &.page-layout-2columns-right,
    &.page-layout-3columns {
      .columns {
        @apply grid-cols-3columns-blog;
      }
    }
  }
}

v4:

css
@media (width >= theme(--breakpoint-xl)) {
  .mpblog-post-view {
    &.page-layout-2columns-left,
    &.page-layout-2columns-right,
    &.page-layout-3columns {
      .columns {
        @apply grid-cols-3columns-blog;
      }
    }
  }
}

WARNING

Custom breakpoints: Venta Theme registers all standard breakpoints in its theme.css. If your project defines additional breakpoints, register them in two places:

  1. In your @theme {} block — so TailwindCSS generates the corresponding utility classes and @media queries compile correctly.
  2. In a :root { --screen-values: ... } rule — Hyvä reads this property at runtime to resolve JavaScript breakpoint checks. If a breakpoint is missing here, those checks will silently return incorrect results even if @theme {} is correct.
Registering --screen-values

Place this in a stylesheet that is always loaded (e.g. base/screen-values.css) and keep it in sync with your @theme {} breakpoints:

css
/* stylelint-disable unit-no-unknown */
:root {
  --screen-values: 2xs:360px,xs:420px,sm:640px,md:768px,lg:1024px,xl:1280px,2xl:1536px;
}

Update class names from custom theme.extend keys

Keys in theme.extend that contained ., %, or / produce new utility class names in v4 (the key encoding rules above apply to generated class names too):

v3 classv4 class
p-71.5, m-71.5p-71-5, m-71-5
p-84%, w-84%p-84-pct, w-84-pct
top-1/10, inset-1/10top-10pct, inset-10pct

Search your theme's .phtml and .xml files for these patterns and replace them.

Advanced: Venta Theme layer proxy override

By default, styles in your components/ folder are loaded after Venta Theme's component layer. This works for most overrides. For highly customized projects where a specific stylesheet inside Venta Theme's layer must be replaced or excluded entirely, use a proxy index.css.

When to use this: you need to remove one of Venta Theme's built-in component stylesheets, not just append styles after it. Adding rules after the fact cannot undo specificity already established by Venta Theme's stylesheet.

Steps:

  1. Create web/tailwind/override/components/index.css.
  2. Copy the contents of vendor/magebitcom/magento2-venta-theme/web/tailwind/components/index.css into it.
  3. In the proxy file, replace the relevant @import line(s) with your local file. Keep all other lines pointing to the original vendor paths — adjust the relative path depth to account for the extra override/components/ directory levels:
css
/* override/components/index.css */

/* Kept from Venta Theme — correct relative path from this file location */
@import "../../../../../../../vendor/magebitcom/magento2-venta-theme/web/tailwind/components/buttons.css";

/* Replaced with project override */
@import "./navigation.css";

/* Kept from Venta Theme */
@import "../../../../../../../vendor/magebitcom/magento2-venta-theme/web/tailwind/components/cards.css";
  1. In tailwind-source.css, swap the direct Venta Theme components import for your proxy:
css
/* Before */
@import "../../../../../../../vendor/magebitcom/magento2-venta-theme/web/tailwind/components/index.css";

/* After */
@import "./override/components/index.css";

WARNING

When Venta Theme is updated, its components/index.css may add or remove files. The proxy file is a manual copy — review it on every Venta Theme upgrade and keep it in sync.

4. Run the TailwindCSS Upgrade Codemod

With the directory clean, tailwind-source.css in place, and your custom CSS migrated, run the official TailwindCSS upgrade codemod from the web/tailwind/ directory:

bash
npx @tailwindcss/upgrade --force

This codemod scans .phtml, layout XML, and CSS files and automatically rewrites the majority of remaining v3 utility formats to their v4 equivalents.

5. Fix Remaining Deprecated Classes

After the codemod, run the Hyvä deprecation report to find any classes the codemod did not handle:

bash
vendor/hyva-themes/upgrade-helper-tools/bin/find-deprecated-classes.js app/design/frontend/Magebit/{ProjectTheme}

The script writes a tailwind-deprecated-report.md and prints output similar to this:

# TailwindCSS Deprecation Report
❌ Found 9 occurrences of deprecated classes:

### FILE: `Magento_Catalog/templates/product/compare/list.phtml`
| Line | Column | Class       | Pattern   |
|------|--------|-------------|-----------|
| 207  | 34     | `flex-grow` | flex-grow |
| 268  | 50     | `flex-grow` | flex-grow |
| 324  | 48     | `flex-grow` | flex-grow |

### FILE: `Magento_Customer/templates/form/register/agreements.phtml`
| Line | Column | Class           | Pattern    |
|------|--------|-----------------|------------|
| 104  | 60     | `bg-opacity-60` | bg-opacity |

### Suggestions
- flex-shrink-* is deprecated. Use `shrink` or `shrink-0` instead.
- flex-grow-* is deprecated. Use `grow` or `grow-0` instead.
- bg-opacity-* is deprecated. Use the new slash syntax for opacity, e.g. `bg-blue-500/50`.

Fix the remaining occurrences via find/replace, or pass the full tailwind-deprecated-report.md to an AI agent and let it apply the replacements across all listed files.

Cross-reference with TailwindCSS — Removed and deprecated utilities for any non-obvious replacements.

Deprecated class reference

Use this table alongside the report above to identify the correct v4 replacement:

v3v4
flex-shrink-0shrink-0
flex-shrinkshrink
flex-growgrow
flex-grow-0grow-0
bg-{color} + bg-opacity-{n}bg-{color}/{n} (e.g. bg-black/50, bg-secondary-700/60)

6. Reconcile Theme Overrides

With the TailwindCSS v4 pipeline building successfully and the storefront rendering, go back and reconcile any manually overridden files that were deferred in §1. Compare your overrides against Venta Theme 1.6.0 changes using the GitHub release diff:

https://github.com/magebitcom/magento2-venta-theme/compare/1.5.x...1.6.0

CI/CD: Ensure generate Runs Before Build

WARNING

generated/hyva-source.css and generated/hyva-tokens.css are not committed to version control. They are created by npm run generate, which runs automatically via the prebuild lifecycle hook when you call npm run build.

In the standard Venta configuration this is hooked into build-prod. Ensure your deployment pipeline calls the correct build target in the theme's web/tailwind/ directory. Also confirm that Venta Theme's own generated dynamic files are rebuilt after a Composer update — if they are not regenerated, the storefront may reference stale assets.

Quick Checklist

  1. Composer: update Venta Theme 1.6.0 + all Venta Theme modules + dependencies.
  2. Install hyva-themes/upgrade-helper-tools (check licence access).
  3. Run convert-to-tailwind-v4.js → backup created, new directory structure in place.
  4. Restore npm dependencies; add .stylelintrc.json; restore full package.json scripts block.
  5. Delete redundant Hyvä Theme layers from base/, components/, theme/; leave empty index.css placeholder per folder or delete unused folders entirely.
  6. Replace tailwind-source.css with the Venta Theme-aware import order.
  7. Configure hyva.config.json; add include paths not in hyva-themes.json; exclude Hyvä Checkout if using Venta Theme checkout.
  8. Restore custom CSS partials from backup; add index.css imports per folder.
  9. Migrate tailwind.browser-jit-config.js tokens → @theme {} in theme.css (or inline in tailwind-source.css).
  10. Replace theme() dot notation → var(--*) in CSS properties.
  11. Replace @screen@media (width >= theme(--breakpoint-*)).
  12. Update class names from encoded theme.extend keys (71.571-5, 84%84-pct, etc.).
  13. Run npx @tailwindcss/upgrade --force.
  14. Run find-deprecated-classes.js; fix remaining deprecations using the deprecated class reference table.
  15. Reconcile deferred theme overrides.
  16. Verify CI/CD pipeline calls build or build-prod in the theme's web/tailwind/ directory, and that Venta Theme's generated dynamic files are also rebuilt.