Node.js
The Node.js container provides npm, pnpm, yarn, and grunt for Hyvä theme Tailwind compilation and front-end asset builds.
Every StoreFrame environment includes a Node.js container that provides JavaScript tooling for front-end asset compilation. Its primary purpose is building Hyvä theme assets — Tailwind CSS compilation, Alpine.js bundling, and the Grunt-based asset pipeline that Magento uses for themes based on the Luma inheritance model. The container runs persistently alongside the rest of the stack and gives you access to npm, pnpm, yarn, and grunt from the VM command line as if they were installed natively.
Version
Node.js version is pinned per Magento release:
| Magento release | Node.js version |
|---|---|
| 2.4.9, 2.4.8, 2.4.7 | 24 |
| 2.4.6 | 20 |
| 2.4.3, 2.4.4, 2.4.5 | 19 |
| 2.3.x | 16 |
| Mage-OS 3.x | 24 |
You can pin a specific version in the environment file (.env):
CONTAINERS__NODEJS_VERSION='24'What runs in the container
The container uses the official node:<version> Docker image. It starts with tail -f /dev/null — it is a persistent tooling container, not a server. Global npm packages are installed into a bind-mounted directory (.docker/npm-global in the project) that survives container recreation:
npmpnpmyarn/yarnpkggrunt-cli
The Magento project directory is bind-mounted into the container at the same path as on the host. This means commands run inside the container operate on the same files as the PHP container, with no file copying required.
The PHP binary is also available inside the Node.js container. This allows build scripts that invoke php bin/magento during a build to work correctly from within the Node.js environment.
Hyvä theme builds
Hyvä is a Magento frontend theme built on Tailwind CSS and Alpine.js. Its CSS is not pre-compiled — it is generated from your theme's templates at deploy time. The Node.js container is what runs that compilation.
The platform does not compile Tailwind for you. At provision time it installs Hyvä through Composer and deploys static content; the default Hyvä theme ships with its CSS already compiled.
When you build your own Hyvä child theme, or change templates so they use new Tailwind classes, compile the CSS yourself from the VM host and commit the result to your repository before you deploy:
# Navigate to the Hyvä theme source directory
cd <magento-root>/app/design/frontend/<vendor>/<theme>/web/tailwind
# Install dependencies (first time or after package.json changes)
npm install
# Build Tailwind CSS
npm run build-prod
# Then deploy static content
php bin/magento setup:static-content:deploy -fThe production build (npm run build-prod) runs PurgeCSS against Magento's PHP templates and Hyvä components to remove unused CSS classes, producing a compact output file. During development, npm run watch compiles without purging and watches for changes.
Host wrapper scripts
The following commands are available on PATH on the VM host. They delegate to docker exec internally:
nodejs --version # Node.js version
npm --version # npm version
pnpm --version # pnpm version
yarn --version # yarn version
grunt --version # Grunt CLI versionWorking directory context is preserved — if you run npm install from inside the Magento root on the host, the command runs inside the container at the same path.
npm global directory
Global npm packages are stored in a directory bind-mounted from <project>/.docker/npm-global on the host to /opt/npm-global inside the container. This means global installs persist across container recreations. The PATH inside the container includes /opt/npm-global/bin.
To install an additional global package:
docker exec node-cli npm install -g <package-name>Operational gotchas
Build fails with EACCES permission errors. The npm global directory is owned by root. If you install a global package as a non-root user and it writes to /opt/npm-global, you may hit permission issues. Run global installs via docker exec node-cli npm install -g (which runs as root inside the container) rather than via the host wrapper.
node_modules not visible to PHP. The Node.js container shares the project directory with the PHP container, but node_modules inside a theme's source directory can accumulate gigabytes over time. They are listed in .gitignore by default. Do not add them to a deployer shared directory.
Tailwind output not visible after build. If npm run build-prod completes without error but the storefront still shows unstyled pages, the static content has not been deployed. After any Tailwind build, run php bin/magento setup:static-content:deploy -f to publish the compiled CSS to pub/static/.
Wrong Node version for a theme. Some Hyvä modules or third-party Node tooling specify engine constraints in package.json. If you see npm WARN EBADENGINE errors, check whether the pinned Node version for your Magento release matches the theme's requirements. You can override the version in .env if the theme requires a newer Node.
Slow first install. The first npm install inside the container downloads packages from the npm registry with no local cache. Subsequent installs are faster if the node_modules directory is not deleted between runs.