RequireJS — Complete AMD Module Loader & JavaScript Guide
RequireJS is a JavaScript file and module loader that implements the AMD (Asynchronous Module Definition) specification, enabling modular, dependency-managed code in the browser.
What You’ll Learn
By the end of this tutorial, you’ll define AMD modules with define(), load dependencies with require(), configure paths and shims for non-AMD libraries, use the r.js optimizer for production builds, and understand how AMD influenced modern ES modules.
Why RequireJS Matters
Before ES modules (2015) and bundlers like Webpack, JavaScript had no native module system. Global scripts loaded in order — and if a dependency was missing, the page broke silently. RequireJS solved this by loading modules asynchronously and managing dependencies automatically. While modern tools have largely replaced RequireJS, its AMD pattern was a foundational step in JavaScript modularization, and millions of legacy applications still depend on it. DodaTech maintains several enterprise products that use RequireJS for modular architecture.
Security note: Understanding Requirejs helps build more secure applications — a core principle at DodaTech, where tools like Durga Antivirus Pro and Doda Browser rely on solid implementation practices.
RequireJS Learning Path
flowchart LR
A[JavaScript Module History] --> B[RequireJS / AMD]
B --> C[Module Definition]
B --> D[Configuration]
B --> E[Shim for Non-AMD]
B --> F[Optimizer]
C --> G[Modern ES Modules]
style B fill:#3b82f6,stroke:#fff,color:#fff
What is AMD? — The Library Card Analogy
Think of the pre-module JavaScript era like a library where all books are piled in the center of the room:
- You grab a book and hope it contains what you need
- If you need “Book A” which references “Book B,” you must find “Book B” yourself
- Nothing tells you when a book is available (loaded)
AMD (RequireJS) is like a library with a card catalog:
- Each book (module) declares what it needs
- The librarian (RequireJS) fetches books in the right order
- You get your book only when all its dependencies are ready
Module Definition with define()
// Define a module named "math" that depends on jQuery
define("math", ["jquery"], function($) {
// This function runs only after jQuery is loaded
return {
add: function(a, b) { return a + b; },
subtract: function(a, b) { return a - b; }
};
});
// Use the module
require(["math", "jquery"], function(math, $) {
console.log(math.add(5, 3)); // 8
$("body").css("background", "blue");
});Line-by-line explanation:
define("math", ["jquery"], function($) { ... })— defines a module named “math” that depends on “jquery”. The factory function receives the dependencies as arguments.return { add: ..., subtract: ... }— the module’s public API. Whatever you return is whatrequire()receives.require(["math", "jquery"], function(math, $) { ... })— loads both modules and calls the callback when all dependencies are ready.
Why this matters: Before AMD, you’d manually add <script> tags in the right order — and if you got the order wrong, the page broke. AMD guarantees correct loading order.
Anonymous Modules (Recommended)
// No module name — filename becomes the ID
// File: js/app/math.js
define(["jquery"], function($) {
return {
add: function(a, b) { return a + b; }
};
});Why anonymous? Named modules couple the filename to the module name. Anonymous modules let you move files without renaming.
Configuration
require.config({
baseUrl: "js/lib", // where to look for modules
paths: {
"jquery": "https://code.jquery.com/jquery-3.7.0.min",
"app": "../app" // path override
},
shim: {
"backbone": {
deps: ["underscore", "jquery"], // dependencies
exports: "Backbone" // global variable name
}
}
});Configuration explained:
baseUrl: "js/lib"— root directory for all modulespaths— map module names to file paths (handy for CDN or directory overrides)shim— required for non-AMD scripts (libraries that use global variables instead ofdefine()). Tells RequireJS what they need and what variable they export.
Non-AMD Libraries (Shim)
Libraries like Backbone (before it supported AMD) expose global variables instead of calling define():
require.config({
shim: {
"backbone": {
deps: ["underscore", "jquery"],
exports: "Backbone"
},
"jquery-plugins": {
deps: ["jquery"]
}
}
});What happens: When require(["backbone"]) is called, RequireJS loads jQuery, then Underscore, then Backbone — and ensures window.Backbone is available before your callback runs.
The Optimizer (r.js)
For production, r.js concatenates and minifies all modules into one file:
node r.js -o baseUrl=js name=main out=main-built.jsThis creates a single main-built.js file containing all dependencies — one HTTP request instead of dozens.
AMD vs CommonJS vs ES Modules
| Feature | AMD (RequireJS) | CommonJS (Node.js) | ES Modules |
|---|---|---|---|
| Syntax | define(), require() | require(), module.exports | import, export |
| Loading | Async | Sync | Async |
| Browser | Native (no build) | Needs bundler | Modern browsers |
| Runtime | Browser | Node.js | Both |
Common Mistakes
1. Forgetting the shim config for non-AMD libraries
If a library uses window.Backbone = ... instead of define(...), it needs a shim entry. Without it, RequireJS loads the script but doesn’t know it’s ready.
2. Circular dependencies
Module A requires Module B, which requires Module A. This breaks the loading order. Restructure to avoid circular references — extract shared code into a third module.
3. Not using the optimizer for production
Loading 50+ individual JS files in production means 50+ HTTP requests. Always run r.js to concatenate everything for deployment.
4. Mixing named and anonymous modules inconsistently
Mixing patterns causes hard-to-debug loading errors. Pick one pattern (anonymous) and stick with it.
5. Confusing require() (AMD) with require() (CommonJS)
In Node.js, require() is synchronous and returns the module. In AMD, require() is asynchronous and takes a callback. Using the wrong pattern in the wrong environment causes bugs.
Practice Questions
1. What problem does RequireJS solve?
Answer: It manages JavaScript dependencies in the browser, loading modules asynchronously in the correct order without manually ordering <script> tags.
2. What is the shim configuration used for?
Answer: Shim configures non-AMD libraries (that use global variables instead of define()) so RequireJS knows their dependencies and exports.
3. What does the r.js optimizer do?
Answer: It concatenates and minifies all AMD modules into a single file for production, reducing HTTP requests and improving load times.
4. How does AMD differ from ES modules?
Answer: AMD uses define()/require() with callbacks (async). ES modules use import/export (syntactic, natively async in browsers).
Challenge
Convert a legacy project that loads 20+ <script> tags in order to use RequireJS with AMD modules. Configure paths and shims for all dependencies, then run the r.js optimizer to produce a single build file.
FAQ
Try It Yourself
# 1. Create project
mkdir requirejs-practice && cd requirejs-practice
# 2. Install RequireJS
npm install requirejs
# 3. Create module files
mkdir -p js/app
cat > js/app/calculator.js << 'EOF'
define([], function() {
return {
add: function(a, b) { return a + b; },
multiply: function(a, b) { return a * b; }
};
});
EOF
cat > js/main.js << 'EOF'
require(["app/calculator"], function(calc) {
console.log("2 + 3 =", calc.add(2, 3));
console.log("4 * 5 =", calc.multiply(4, 5));
});
EOF
# 4. Create index.html with RequireJS
cat > index.html << 'EOF'
<!DOCTYPE html>
<html>
<head>
<title>RequireJS Demo</title>
</head>
<body>
<script data-main="js/main" src="node_modules/requirejs/require.js"></script>
</body>
</html>
EOF
# 5. Serve with any HTTP server and open in browser
# npx serve .What’s Next
Explore more JavaScript tools and patterns:
| Topic | Description |
|---|---|
| https://tutorials.dodatech.com/tools/rxjs/ | Reactive programming with Observables |
| https://tutorials.dodatech.com/tools/lodash/ | JavaScript utility library |
| https://tutorials.dodatech.com/tools/babeljs/ | JavaScript transpiler |
Related topics to explore:
- JavaScript Modules
- Node.js CommonJS
- Build Tooling Evolution
What’s Next
Congratulations on completing this Requirejs tutorial! Here’s where to go from here:
- Practice daily — Consistency is more important than long study sessions
- Build a project — Apply what you learned by building something real
- Explore related topics — Check out other tutorials in the same category
- Join the community — Discuss with other learners and share your progress
Remember: every expert was once a beginner. Keep coding!
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro