Skip to content
RequireJS — Complete AMD Module Loader & JavaScript Guide

RequireJS — Complete AMD Module Loader & JavaScript Guide

DodaTech Updated Jun 6, 2026 7 min read

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
  
Prerequisites: Solid JavaScript fundamentals. Understanding of Node.js modules is helpful but not required.

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 what require() 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 modules
  • paths — map module names to file paths (handy for CDN or directory overrides)
  • shim — required for non-AMD scripts (libraries that use global variables instead of define()). 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.js

This creates a single main-built.js file containing all dependencies — one HTTP request instead of dozens.

AMD vs CommonJS vs ES Modules

FeatureAMD (RequireJS)CommonJS (Node.js)ES Modules
Syntaxdefine(), require()require(), module.exportsimport, export
LoadingAsyncSyncAsync
BrowserNative (no build)Needs bundlerModern browsers
RuntimeBrowserNode.jsBoth

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

What is RequireJS?
RequireJS is a JavaScript module loader that implements the AMD specification, enabling asynchronous, dependency-managed module loading in the browser.
Is RequireJS still used?
Modern projects use ES modules with Webpack or Vite. But millions of legacy applications still use RequireJS, and it’s important for maintaining and migrating these systems.
What is the difference between AMD and CommonJS?
AMD is designed for browsers (async loading), uses define() and callback-based require(). CommonJS is designed for Node.js (sync loading), uses require() and module.exports.
How do I use non-AMD libraries with RequireJS?
Use the shim configuration to declare dependencies and exports for libraries that use global variables instead of define().
What is r.js?
r.js is the RequireJS optimizer that concatenates and minifies AMD modules into a single production file.
Can RequireJS work with Node.js?
Yes, through the AMD adapter, but it’s rarely done. Node.js natively supports CommonJS and (since v12+) ES modules.

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:

TopicDescription
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:

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