Skip to content
5.0 Upwork, 100+ reviews Adobe Certified since 2021 New: become your own Magento developer Learn more →
Magento glossary

What is Magento RequireJS?

Short answer Magento RequireJS is the AMD (Asynchronous Module Definition) JavaScript loader that Magento 2 uses on the Luma storefront and in the admin. Each module can ship a view/frontend/requirejs-config.js, Magento merges all of them into one config file, and code loads its dependencies with require([…]) or define([…]). If you work on a Luma-based store or on the admin, you deal with RequireJS every day. Hyvä drops it on the storefront and uses Alpine.js and plain JavaScript instead.

How it works
  1. Each module ships a requirejs-config.js with its JS module map 01
  2. Magento walks every enabled module and merges configs into one file 02
  3. Templates hand control to RequireJS via x-magento-init 03
  4. RequireJS resolves the module name to a static file URL and fetches it 04
  5. The AMD factory’s return value is wired to the calling block 05
Each step is explained below

Most common mistake Dropping a raw <script> tag instead of declaring an AMD module

How it works

Five steps from module config to executing AMD callback

This is the path a piece of JavaScript takes from a module folder to a running component on the page. When a script does not load, I go through these steps in this order.

  1. 01

    Each module ships a requirejs-config.js with its JS module map

    A module with its own storefront JavaScript adds Vendor/Module/view/frontend/requirejs-config.js (or view/adminhtml/requirejs-config.js for the admin). The file sets one object: var config = { map: {...}, paths: {...}, deps: [...], shim: {...} }. I use map to point one module name at another file, paths for short aliases, deps for modules that should load on every page, and shim for older libraries that are not written as AMD modules. Mixins also go here, under config.mixins.

  2. 02

    Magento walks every enabled module and merges configs into one file

    Magento collects the requirejs-config.js of every enabled module and theme and merges them into one file. In 2.4 that file lives under pub/static/_requirejs/frontend/<Vendor>/<theme>/<locale>/requirejs-config.js. In production mode it is only rebuilt during bin/magento setup:static-content:deploy, so when I change a config file and nothing happens on the storefront, a missing static deploy is the first thing I check.

  3. 03

    Templates hand control to RequireJS via x-magento-init

    A .phtml template that needs JavaScript prints <script type="text/x-magento-init">{"*": {"Vendor_Module/js/component": {"config":"value"}}}</script>. After RequireJS loads, the mage/apply/main.js script from lib/web finds these tags and calls require() for each component, passing it the config and the element. "*" means the component is not tied to an element. You can target one element with "#my-element": {...}, or put a data-mage-init attribute directly on the node.

  4. 04

    RequireJS resolves the module name to a static file URL and fetches it

    Using the merged config, RequireJS turns Vendor_Module/js/component into pub/static/frontend/<Vendor>/<theme>/<locale>/Vendor_Module/js/component.js and loads it with an async <script> tag. The file has to be an AMD module, wrapped in define(['jquery', 'ko', 'mage/translate'], function($, ko, $t){ ... }). RequireJS loads each dependency first, keeps every loaded module in memory, and runs the factory function once all of them are ready.

  5. 05

    The AMD factory’s return value is wired to the calling block

    Whatever the factory function returns is what Magento calls. For a jQuery widget, Magento effectively runs $(element).widgetName(config). For a plain function component, Magento calls it with (config, element). For UI components, Magento_Ui/js/core/app creates the component instances from the JSON layout config and Knockout renders their templates. From there the component can require() more modules on demand, send AJAX requests and bind its own events.

When to use

Four scenarios where you cannot avoid RequireJS

On a Luma storefront and in the admin, all four of these go through RequireJS. If you skip it and add loose script tags, things tend to break later, often when JS bundling or minification is switched on.

  • Adding any custom JS to a Luma storefront page

    On Luma, custom JavaScript goes through RequireJS. I put the code in view/frontend/web/js/ as an AMD module, so it is available as Vendor_Module/js/file without any extra config, and load it from the template with <script type="text/x-magento-init"> or data-mage-init. I only add a map['*'] alias in requirejs-config.js when other modules need a short global name for it. A raw <script> tag may work on your machine and then break once bundling, minification or a different load order comes into play.

  • Customizing a KnockoutJS UI Component

    Checkout, the minicart, the product gallery and admin grids are all UI components, and each one is a RequireJS module such as Magento_Checkout/js/view/shipping. The component is configured in layout XML (jsLayout) or in a ui_component XML file, and its HTML template lives in view/frontend/web/template/. To change one, I either swap the class path with map['*'], add behaviour with a mixin under config.mixins, or change the component entry in the layout. All three depend on how RequireJS merges config, so it pays to know those rules first.

  • Adding an admin JS widget

    The admin uses the same RequireJS setup as the storefront, with its own merged config for the Magento/backend theme. I add view/adminhtml/requirejs-config.js to the module when admin JavaScript needs aliases or mixins, and load the code from admin .phtml templates with the same x-magento-init pattern. Merging, caching and static deploy work the same way as on the storefront.

  • Overriding or extending a core module’s JS

    To replace a core file such as Magento_Checkout/js/view/payment, I add a map['*'] alias in requirejs-config.js: map: { '*': { 'Magento_Checkout/js/view/payment': 'Vendor_Module/js/view/payment' } }. Every require(['Magento_Checkout/js/view/payment']) in any module then gets my file. When I only need to add or change one method, I use a mixin instead. A mixin wraps the original, so core fixes in later releases still reach the store and I do not have to copy them into my file.

Common mistakes

Three RequireJS pitfalls that break Magento JS in production

Every “why is my Magento JS broken in production” engagement I’ve been called in to fix tracks back to one of these. Audit your custom JS against the list before going live.

  • Dropping a raw <script> tag instead of declaring an AMD module

    The single most common Magento JS mistake: a developer needs “just a small inline script” and emits a literal <script>require(['jquery'], function($){...});</script> in a .phtml. It works in dev, then breaks in production because the script tag runs before RequireJS is loaded, you get Uncaught ReferenceError: require is not defined. The fix: always go through <script type="text/x-magento-init"> or data-mage-init on a DOM node, and put the actual code in a proper define() AMD module under your module’s view/frontend/web/js/.

  • Forgetting to rebuild static content after editing requirejs-config.js

    The merged requirejs-config.js sits at pub/static/frontend/<theme>/<locale>/requirejs-config.js on disk. When you edit your module’s per-module config, nothing on the storefront changes until the merged file is regenerated. Symptoms: “my new RequireJS alias isn’t picked up”, “my mixin doesn’t fire”. Fix: rm -rf pub/static/frontend/* pub/static/_cache var/view_preprocessed, then bin/magento setup:static-content:deploy -f en_US, then a browser hard-refresh to bust the CDN.

  • Flipping dev/js/enable_js_bundling=1 without testing

    Magento’s built-in JS bundler concatenates AMD modules into bundle files served by require.js. On paper this kills round-trips; in practice the default bundler is brittle on Luma, it routinely breaks lazy-loaded modules, mini-cart hydration, and address validation, and the bundle file is megabytes (~10MB+) on a stock Luma store. Test on staging before flipping it on. For real performance gains, use a custom bundler like Baler (github.com/magento/baler) or upgrade to Hyvä, the latter removes RequireJS entirely. Default-stack: keep bundling off, keep dev/js/minify_files=1, keep dev/js/merge_files=0.

FAQ

Magento RequireJS, frequently asked questions

  • RequireJS vs ES modules, why does Magento still use AMD in 2026?
    Backward compatibility plus inertia. Magento 2.0 shipped in 2015 and committed to AMD via RequireJS as the storefront JS module format. By the time native browser ES modules landed (2017-ish), the Magento ecosystem had thousands of third-party extensions all written as AMD define() blocks. Migrating to ES modules would break every single one of them. Adobe’s answer is Hyvä, a clean-room storefront theme that drops RequireJS entirely in favour of native ES modules plus Alpine.js. If you’re starting fresh, build on Hyvä. If you’re on Luma, you’re on RequireJS for the lifetime of the storefront unless you do a full theme rewrite.
  • Why does my requirejs-config.js change not load?
    The merged config file is cached on disk at pub/static/frontend/<theme>/<locale>/requirejs-config.js. Editing your module’s per-module config does not regenerate that file, you have to wipe the static-content cache and redeploy. The full ritual: rm -rf pub/static/frontend/* pub/static/_cache/merged var/view_preprocessed, then bin/magento setup:static-content:deploy -f en_US, then hard-refresh the browser to clear the local cache, then purge the CDN (Cloudflare, Fastly, whatever) because the old requirejs-config.js URL was probably edge-cached too.
  • Can I use ES modules inside a Luma Magento module?
    Yes, with caveats. Inside your AMD module you can use modern ES syntax (arrow functions, destructuring, async/await) because the file is parsed by the browser’s JS engine, not RequireJS itself. What you cannot do is use import / export, the entry point that Magento loads via x-magento-init must be a wrapping define([...], function(){...}) AMD block. If you want to internally import from a sibling ES module, declare each one as its own AMD define, declare it as a dep in the outer module, and let RequireJS resolve the graph. Don’t try to mix native <script type="module"> into a Luma storefront, that bypasses Magento’s bootstrap and breaks under FPC.
  • What is mage/translate?
    A RequireJS module that provides Magento’s frontend translation helper. Declared in Magento_Translation/view/frontend/requirejs-config.js, it exposes $.mage.__('Some text'), the JS equivalent of PHP’s __('Some text'). Inside your AMD module: define(['jquery', 'mage/translate'], function($, $t){ var label = $t('Add to cart'); });. Translation strings are pulled from the same i18n CSV / dictionary files the PHP side reads, you don’t duplicate them. If a string isn’t translated, mage/translate returns the original English. It is the only correct way to translate JS strings; never hardcode language strings inside AMD modules.
  • How do I disable RequireJS bundling without losing minification?
    Three admin config flags under Stores → Configuration → Advanced → Developer → JavaScript Settings: set Enable JavaScript Bundling = No (dev/js/enable_js_bundling=0), Minify JavaScript Files = Yes (dev/js/minify_files=1), and Merge JavaScript Files = No (dev/js/merge_files=0). Merge is an old HTTP/1 optimisation that hurts more than it helps on HTTP/2. Minify-on, merge-off, bundle-off is the safest production default for Luma. Then run bin/magento setup:static-content:deploy -f en_US. For real bundle performance, use Baler or Hyvä instead of the built-in bundler.
  • Does Hyvä really not load RequireJS at all?
    Correct, check the network panel on a Hyvä storefront and you will not find require.js or requirejs-config.js anywhere. Hyvä uses native ES modules loaded via <script type="module"> for declarative behaviour and Alpine.js for inline reactivity. The bundle size drops from ~2.5MB of compressed JS on Luma to ~150KB on Hyvä for the same storefront, and the JS execution time on first paint drops from 600-800ms to under 100ms. RequireJS in 2026 is the single biggest reason Luma is hard to performance-tune, if PageSpeed Insights and Core Web Vitals matter to you, the migration to Hyvä is the answer.
Magento JS audit

Stuck on a RequireJS error on a Magento storefront?

Send your storefront URL and the error message, I will inspect your requirejs-config.js merge, x-magento-init usage, mixin wiring, and JS bundling settings, then reply with a written fix plan, fixed-price quote, and earliest start date. 24-business-hour turnaround.

Kishan Savaliya Online 10 AM to 7 PM IST Chat on WhatsApp