RequireJS part 1: the AMD pattern, and basic module definition

What's AMD, what's RequireJS, and how to define and require modules. And by "scratch" I mean from the ground up, for absolute beginners.


AMD (Asynchronous Module Definition) is a module definition specification, which lives in the amdjs group. Since AMD isn’t at the core of my artistry, it’s better to quote trusted sources.

The AMD module format itself is a proposal for defining modules where both the module and dependencies can be asynchronously loaded. src

This is what Wikipedia has to say about AMD.

Asynchronous module definition (AMD) is a JavaScript specification that defines an API for defining code modules and their dependencies, and loading them asynchronously if desired. src


If AMD is the underlying spec, the RequireJS is a tool that uses the AMD API to load in small modules of code asynchronously.


Traditionally you stuff all JavaScript into one file (because you want to avoid multiple, slow HTTP requests), load that in the footer and that’s it. This works swimmingly on small sites, but what if those sites get colossal? With that method, the script file bloats into a big ball of mud, and your workday resemble rather a Kenny G concert than a foot massage. Plus, if there are more developer working on the project, and you only got very few files, merge conflicts sure make life unpleasant.

Okay then, split it to multiple smaller files and load them with separate requests. To an extent this works, but is not a permanent solution. It’s slow, and the load order of the scripts might not be right, the headaches are on their way again.

The modules defined with RequireJS also don’t pollute the global namespace.

AMD is a light that illuminates the path out of the Kenny G concert.

Among other things, AMD makes code:

  • Manageable
  • Reusable
  • Faster
  • Encapsulated
  • Compartmentalized (always wanted to use that word)

When the code is split across multiple files, each developer can work on smaller junks of code at each given time. Better encapsulation and less merge conflicts. The modules are always loaded in the right order, and asynchronously. Asynchronous loading doesn’t block anything else from loading.

This video by Gary Landholt is extremely illuminating if you’re still having doubts why modules are a great thing.

But it’s still many files, how’s stat good?

Yeah, there are a lot of small files that all get loaded separately, even if they are loaded asynchronously, it’s still very bad for page speed. That’s why there is r.js, an optimization tool that concatenates modules into one. You’d then load this file in production. Problem solved. More on that on the second part of the article.

Example project

I’ve made a little starter template to test and isolate RequireJS use cases. View it here (it’s run straight from GitHub via RawGit), or clone it:

$ git clone
# Or via https
$ git clone

Relevant bits of the directory structure:

├── index.html                 // The main HTML file
├── js
│   ├── config.js              // RequireJS config file and main entry point
│   └── modules
│       ├── app.js             // The actual logic
│       ├── classes.js         // Module
│       ├── cookies.js         // Ditto
│       ├── debounce.js
│       ├── dimensions.js
│       ├── hider-shower.js
│       ├── media-queries.js
│       └── sticky-position.js
└── lib                        // All the external libraries and deps
    ├── jquery.js
    ├── normalize.css
    ├── require.js
    └── zepto.js

Using RequitreJS

This goes into your sites footer:

<script src="lib/require.js" data-main="js/config"></script>


No thrills, plain old, script load.
This then again, is our entry point to the RequireJS, it’s also where we configure the it, hence the name. Oftentimes it might also be called main.js. Note that file extension is not needed, because RequireJS only loads JavaScript files.

There are ample ways to use RequireJS, this is just one.

The config file

The config file is the entry point to RequireJS, it lives in src/js/config.js:

    baseUrl: 'js',
    deps: ['modules/app'],
    paths: {
        jquery: '../lib/jquery'

Here’s listed what all the constituent parts do:

baseUrl: 'js'
If you used the data-main attribute to load RequireJS (see above) then you don’t need this, it’s set already. But you might want to change that perhaps.
deps: ['modules/app']
This defines an array of dependencies to load, modules/app in this case. the app.js is where we require and use all the modules, it’s the heart of our app.
paths: {jquery: '../lib/jquery'}
This defines a path to module, jQuery in this case. This is not mandatory, then you just have to refer to jQuery as ../lib/jquery, but for convenience it’s recommended. Note again the lack of the file extension, this could be written also as ../lib/jquery.js, but there is no need to do that.

Noteworthy thing: jQuery supports AMD loading out the box, so we don’t have to define it as a module, cause it’s already done in the code.

Config file might be called main or app, I quite like the config approach. Here’s some patterns on how to separate the config from the main file.

Defining modules with dependencies

See the “Show Nav” button in the demo, it’s made possible by the hider-shower.js file. Essentially, we want to define the hider-shower as a module. But first let’s look this simplified example module that takes jQuery as a dependency:

define(['jquery'], function($) {
    $('.some-element').css('background', 'Pink');

define takes two argument:

  1. Array of dependencies — RequireJS makes sure these get loaded before the modules code is run, in this case it makes sure that jQuery is loaded.
  2. Definition function — takes as a parameter what the dependencies export, in jQuery it’s the dollar $ symbol. Then we have access to that dollar in our module.

Noteworthy thing: we’re not defining a name for the module at all, because the file name becomes the module name. We’ll look the requiring of the modules later on.

Noteworthy thing #2: This array ['jquery'], magically loads in jQuery, because jQuery supports AMD. If it wouldn’t support AMD, we would have to define the jQuery as a module first, and only then we could load it.

Noteworthy thing #3: ['jquery'] refers to the name we cave it in the config.js in he paths object. If we hadn’t done that, we’d have to refer it with its path [../lib/jquery].

Here’s the full code for the hider shower:

define(['jquery'], function($) {
     * Show a hidden element, also hides it when clicking out of it
     * @param  {string} trigger The button to show the element
     * @param  {string} el      The element to toggle
    return hiderShower = function(trigger, el) {
        var $trigger = $(trigger),
            $el = $(el);
        $(document).on('click', function(event) {
            // If the trigger element is clicked
            if ($($trigger).length) {
            // If anything else than the element is clicked
            } else if (!$( {

See that we are returning a function. That return value is what gets emitted when we require the modules.

Defining modules with no deps

In the demo, the header sticks to the top when it’s about to leave the viewport. The sticky-position.js file enables that, and it’s just pure JavaScript, there’s no deps:

define(function() {
    return {
         * Add a class `sticky` to the header when it's about to leave the
         * viewport
         * @param  {string} el     The wanted element e.g `header`
         * @param  {int}    offset The offset
        stickyPosition: function(el, offset) {
            // The element
            var el = document.querySelector(el),
                // Offset from top
                origOffsetY = el.offsetTop;

            // The locig
            var sticker = function() {
                if (window.scrollY > origOffsetY) {
                } else {


            // Event listener
            document.addEventListener('scroll', sticker);

The define only parameter is function.

The contents of the module is also different from the hider-shower module, in the sense that it returns an object, not a function. Both are valid ways to use RequireJS, though. It’s up to you.

Loading modules

We’ve defined two modules: hider-shower and sticky-position. Let’s put them in use next.

The app.js is where we require our modules. The app.js is also defined as a module, but we’ll do that a bit differently with “simplified define wrapper” (more on that later):

define(function(require) {
    // Requires calls and app logic here

Inside this module we got an access to require function:

define(function(require) {
    // Here we require the hider-shower module

Note: we use a path here to require the module require('./hider-shower').

Now access the required module:

define(function(require) {
    // Here we require the hider-shower module

    // Access the modules return value, which happens
    // to be the `hiderShower` function
    hiderShower('.hider-shower-button', '.main-nav');

Any code can be written into the app.js file. I mostly write functions in their modules and then require and use them in the app.js along the rest of the app logic.

Loading the sticky-positioning module is a bit different since it returns an object:

define(function(require) {
    // Require
    sticky = require('./sticky-position')

    // Use
    var header = document.getElementById('header');
    if (header != null) {

About the simplified define wrapper

The reason we use the “simplified define wrapper” is that our app module has tons of dependencies, cause it’s the main file, pretty much all the modules are it’s dependencies. Without it, things would look messy and confusing:

    './dimensions', 'echo', './classes', './sticky-position',
    './color-changer', './debounce', './has-child', './hider-shower',
     './keyboard', './lazy-codepen', './lazy-vimeo', './link-opener',
     './toctoc', './media-queries'
    dim, echo, classes, sticky, colorChanger, debounce, hasChild,
    hiderShower, kb, laztcp, lazyVimeo, linkOpener, toc, mq
) {
    // App logic

It’s hard to know what import what blah… Hence, the simplified define wrapper:

define(function(require) {
    var dep1 = require('dependency1'),
        dep2 = require('dependency2');

    return function () {};

Noteworthy thing: there’s also the “Simplified CommonJS Wrapper” which is a bit of different thing, read more about it in the docs, and heres a good read also: Differences between the simplified CommonJS wrapper and standard AMD define.

What gets loaded? How? And in what order?

All the modules and their deps get loaded, individually as separate files. If you peek in the devtools, for instance, jQuery is last on the list, how can that be, it’s used by the other modules? For what I understand, the files get loaded in whatever asynchronously order, but then get executed in the right order.

Screenshot 2015-02-19 22.58.42

If you pop the inspector open in the demo and look in the head section, all the modules are injected there as script tags.

There’s quite a many files loaded just for a very simple site, that’s not very wise is it? Using RequireJS without optimizing the code is not advisable, like using an unminified code isn’t that wise.

There are tools to turn modularized RequireJS code into plain old non modular JavaScript. In the part 2 of this article we’re gonna look just that, and how to concatenate the modules into one, Gulp will do all the heavy lifting. I’ll link it here when it’s published.


There’s tons of different ways to use RequireJS, this is just one. RequireJS is totally worth the effort to learn, it might seem complex at first but it’s quite simple in the end. This post only scraped the surface of things, there’s so much more to it.

Please drop a comment if I got it wrong or was unclear somehow.


Club-Mate, the beverage →