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.
- Each module ships a requirejs-config.js with its JS module map 01
- Magento walks every enabled module and merges configs into one file 02
- Templates hand control to RequireJS via x-magento-init 03
- RequireJS resolves the module name to a static file URL and fetches it 04
- The AMD factory’s return value is wired to the calling block 05
Most common mistake Dropping a raw <script> tag instead of declaring an AMD module
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.
-
01
Each module ships a
requirejs-config.jswith its JS module mapA module with its own storefront JavaScript adds
Vendor/Module/view/frontend/requirejs-config.js(orview/adminhtml/requirejs-config.jsfor the admin). The file sets one object:var config = { map: {...}, paths: {...}, deps: [...], shim: {...} }. I usemapto point one module name at another file,pathsfor short aliases,depsfor modules that should load on every page, andshimfor older libraries that are not written as AMD modules. Mixins also go here, underconfig.mixins. -
02
Magento walks every enabled module and merges configs into one file
Magento collects the
requirejs-config.jsof every enabled module and theme and merges them into one file. In 2.4 that file lives underpub/static/_requirejs/frontend/<Vendor>/<theme>/<locale>/requirejs-config.js. In production mode it is only rebuilt duringbin/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. -
03
Templates hand control to RequireJS via
x-magento-initA
.phtmltemplate that needs JavaScript prints<script type="text/x-magento-init">{"*": {"Vendor_Module/js/component": {"config":"value"}}}</script>. After RequireJS loads, themage/apply/main.jsscript fromlib/webfinds these tags and callsrequire()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 adata-mage-initattribute directly on the node. -
04
RequireJS resolves the module name to a static file URL and fetches it
Using the merged config, RequireJS turns
Vendor_Module/js/componentintopub/static/frontend/<Vendor>/<theme>/<locale>/Vendor_Module/js/component.jsand loads it with an async<script>tag. The file has to be an AMD module, wrapped indefine(['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. -
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/appcreates the component instances from the JSON layout config and Knockout renders their templates. From there the component canrequire()more modules on demand, send AJAX requests and bind its own events.
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 asVendor_Module/js/filewithout any extra config, and load it from the template with<script type="text/x-magento-init">ordata-mage-init. I only add amap['*']alias inrequirejs-config.jswhen 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 aui_componentXML file, and its HTML template lives inview/frontend/web/template/. To change one, I either swap the class path withmap['*'], add behaviour with a mixin underconfig.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/backendtheme. I addview/adminhtml/requirejs-config.jsto the module when admin JavaScript needs aliases or mixins, and load the code from admin.phtmltemplates with the samex-magento-initpattern. 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 amap['*']alias inrequirejs-config.js:map: { '*': { 'Magento_Checkout/js/view/payment': 'Vendor_Module/js/view/payment' } }. Everyrequire(['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.
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 moduleThe 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 getUncaught ReferenceError: require is not defined. The fix: always go through<script type="text/x-magento-init">ordata-mage-initon a DOM node, and put the actual code in a properdefine()AMD module under your module’sview/frontend/web/js/. -
Forgetting to rebuild static content after editing
requirejs-config.jsThe merged
requirejs-config.jssits atpub/static/frontend/<theme>/<locale>/requirejs-config.json 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, thenbin/magento setup:static-content:deploy -f en_US, then a browser hard-refresh to bust the CDN. -
Flipping
dev/js/enable_js_bundling=1without testingMagento’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, keepdev/js/minify_files=1, keepdev/js/merge_files=0.
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 AMDdefine()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.jschange not load?The merged config file is cached on disk atpub/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, thenbin/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 oldrequirejs-config.jsURL 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 useimport/export, the entry point that Magento loads via x-magento-init must be a wrappingdefine([...], function(){...})AMD block. If you want to internally import from a sibling ES module, declare each one as its own AMDdefine, 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 inMagento_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/translatereturns 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 underStores → Configuration → Advanced → Developer → JavaScript Settings: setEnable JavaScript Bundling = No(dev/js/enable_js_bundling=0),Minify JavaScript Files = Yes(dev/js/minify_files=1), andMerge 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 runbin/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 findrequire.jsorrequirejs-config.jsanywhere. 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.
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.