What is Magento RequireJS ?
Magento RequireJS is the AMD (Asynchronous Module Definition) JavaScript loader Magento 2 ships since 2.0 as its storefront and admin JS dependency manager. Every module declares its module map in view/frontend/requirejs-config.js; Magento merges all enabled-module configs into a single file at runtime, and code calls require([…]) which resolves through that merged map. Required in Luma and the admin; removed entirely in Hyvä, which uses native ES modules plus Alpine.js.
Five steps from module config to executing AMD callback
RequireJS is not magic — Magento walks every module, merges configs, and hands control to RequireJS via a documented bootstrap. Here is the wiring, end to end.
-
01
Each module ships a
requirejs-config.jswith its JS module mapA Magento module declaring custom storefront JS drops a config file at
Vendor/Module/view/frontend/requirejs-config.js(orview/adminhtml/requirejs-config.jsfor the admin). That file exports a singlevar config = { map: {...}, paths: {...}, deps: [...], shim: {...} }block.mapaliases module names (Vendor_Module/js/widget→ physical path);pathsrewrites paths;depsdeclares modules to auto-load on page boot;shimwraps legacy non-AMD libraries so RequireJS can still pull them in. -
02
Magento walks every enabled module and merges configs into one file
At storefront boot Magento’s
Magento\RequireJs\Model\FileManageriterates the ComponentRegistrar list, reads every enabled module’srequirejs-config.js, and concatenates them into a singlerequirejs-config.jsserved atpub/static/frontend/<theme>/<locale>/requirejs-config.js. The merged file is cached on disk — any change to a per-module config needs a static-content rebuild before the storefront sees it (see [[feedback_static_content_force_rebuild]]). -
03
Templates hand control to RequireJS via
x-magento-initA
.phtmltemplate that wants to load custom JS emits<script type="text/x-magento-init">{"*": {"Vendor_Module/js/component": {"config":"value"}}}</script>. Magento_Ui’smage/apply/main.jsbootstrap scans the DOM for these script tags after RequireJS loads, then callsrequire(["Vendor_Module/js/component"], function(c){ c(config, selector); }). The selector"*"means “page-wide”; you can also target a specific element via"#my-element": {...}or usedata-mage-initon a DOM node directly. -
04
RequireJS resolves the module name to a static file URL and fetches it
The merged config tells RequireJS that
Vendor_Module/js/componentresolves topub/static/frontend/<theme>/<locale>/Vendor_Module/js/component.js. The file is requested with an async<script>tag, parsed as an AMD module — it must be wrapped indefine(['jquery', 'ko', 'mage/translate'], function($, ko, $t){ ... }). RequireJS recurses into each declared dependency, caching every resolved module, and once all dependencies are loaded the factory function runs. -
05
The AMD factory’s return value is wired to the calling block
Whatever the AMD factory
returns — typically a Component constructor, a jQuery widget factory, or a KnockoutJS ViewModel class — is what x-magento-init hands back. For UI Components, Magento instantiates the class with the JSON config; for jQuery widgets, Magento calls$(selector).widgetName(config); for ViewModels, Magento binds the instance viako.applyBindings. The component then takes over: it can callrequire()recursively for lazy dependencies, fire AJAX, render templates, and bind UI events.
Four scenarios where you cannot avoid RequireJS
On a Luma storefront, these four scenarios all route through RequireJS. Skip the wiring and you get loose script tags that break under bundling, FPC, or CDN edge caches.
-
Adding any custom JS to a Luma storefront page
On a Luma storefront, custom JS goes through RequireJS — that’s not optional, it’s how Magento expects to wire frontend behaviour. Declare your module’s entry point in
view/frontend/requirejs-config.jsundermap['*']if it’s a global alias, or just leave it discoverable via the standardVendor_Module/js/filenaming convention. Load it from a.phtmltemplate with<script type="text/x-magento-init">. Skipping RequireJS and dropping a raw<script>tag will work locally but breaks once you turn on JS bundling, full-page cache, or move to a CDN. -
Customizing a KnockoutJS UI Component
Every Magento UI Component — checkout, mini-cart, product gallery, admin grids — is a RequireJS module under the hood. The component XML (
view/frontend/web/template/...) points at a JS class loaded via RequireJS asVendor_Module/js/view/checkout/foo. Customizing means either overriding the class path viamap['*']in yourrequirejs-config.js, mixing in behaviour via aconfig['mixins']entry, or replacing the entire component definition. All three routes go through RequireJS — understand its merge rules before you start. -
Adding an admin JS widget
The Magento admin runs on the same RequireJS pipeline as the storefront, just with its own merged config at
pub/static/adminhtml/<theme>/en_US/requirejs-config.js. Add aview/adminhtml/requirejs-config.jsin your module to register admin JS modules; load them from admin.phtmltemplates via the samex-magento-initpattern. The admin theme isMagento/backend; the locale is the admin user’s locale. Everything else matches storefront RequireJS — same merge, same cache, same static-content rebuild rules. -
Overriding or extending a core module’s JS
The cleanest way to override a core JS file (say
Magento_Checkout/js/view/payment) is amap['*']alias in yourrequirejs-config.js:map: { '*': { 'Magento_Checkout/js/view/payment': 'Vendor_Module/js/view/payment' } }. RequireJS will resolve everyrequire(['Magento_Checkout/js/view/payment'])in any module to your file instead of the core one. For additive behaviour (don’t replace, just extend) use themixinsmechanism inrequirejs-config.js— cleaner because you don’t inherit the burden of merging upstream changes.
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. See [[feedback_static_content_force_rebuild]] for the full ritual. -
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 AMD <code>define()</code> 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 <code>requirejs-config.js</code> change not load?
The merged config file is cached on disk at <code>pub/static/frontend/<theme>/<locale>/requirejs-config.js</code>. 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: <code>rm -rf pub/static/frontend/* pub/static/_cache/merged var/view_preprocessed</code>, then <code>bin/magento setup:static-content:deploy -f en_US</code>, then hard-refresh the browser to clear the local cache, then purge the CDN (Cloudflare, Fastly, whatever) because the old <code>requirejs-config.js</code> URL was probably edge-cached too. See [[feedback_static_content_force_rebuild]] for the recipe I run on this site. -
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 <code>import</code> / <code>export</code> — the entry point that Magento loads via x-magento-init <em>must</em> be a wrapping <code>define([...], function(){...})</code> AMD block. If you want to internally import from a sibling ES module, declare each one as its own AMD <code>define</code>, declare it as a dep in the outer module, and let RequireJS resolve the graph. Don’t try to mix native <code><script type="module"></code> into a Luma storefront — that bypasses Magento’s bootstrap and breaks under FPC. -
What is <code>mage/translate</code>?
A RequireJS module that provides Magento’s frontend translation helper. Declared in <code>Magento_Translation/view/frontend/requirejs-config.js</code>, it exposes <code>$.mage.__('Some text')</code> — the JS equivalent of PHP’s <code>__('Some text')</code>. Inside your AMD module: <code>define(['jquery', 'mage/translate'], function($, $t){ var label = $t('Add to cart'); });</code>. 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, <code>mage/translate</code> 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 <code>Stores → Configuration → Advanced → Developer → JavaScript Settings</code>: set <code>Enable JavaScript Bundling = No</code> (<code>dev/js/enable_js_bundling=0</code>), <code>Minify JavaScript Files = Yes</code> (<code>dev/js/minify_files=1</code>), and <code>Merge JavaScript Files = No</code> (<code>dev/js/merge_files=0</code>). 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 <code>bin/magento setup:static-content:deploy -f en_US</code>. 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 <code>require.js</code> or <code>requirejs-config.js</code> anywhere. Hyvä uses native ES modules loaded via <code><script type="module"></code> 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.