The JavaScript blog.


tutorials frameworks libraries modules ender

How Ender Bundles Libraries for the Browser

Posted on .

This is a contributed post by Rod Vagg. This work is licensed under a Creative Commons Attribution 3.0 Unported License.

I was asked an interesting Ender question on IRC (#enderjs on Freenode) and as I was answering it, it occurred to me that the subject would be an ideal way to explain how Ender's multi-library bundling works. So here is that explanation!

The original question went something like this:

When a browser first visits my page, they only get served Bonzo (a DOM manipulation library) as a stand-alone library, but on returning visits they are also served Qwery (a selector engine), Bean (an event manager) and a few other modules in an Ender build. Can I integrate Bonzo into the Ender build on the browser for repeat visitors?

What's Ender?

Let's step back a bit and start with some basics. The way I generally explain Ender to people is that it's two different things:

  1. It's a build tool, for bundling JavaScript libraries together into a single file. The resulting file constitutes a new "framework" based around the jQuery-style DOM element collection pattern: $('selector').method(). The constituent libraries provide the functionality for the methods and may also provide the selector engine functionality.
  2. It's an ecosystem of JavaScript libraries. Ender promotes a small collection of libraries as a base, called The Jeesh, which together provide a large portion of the functionality normally required of a JavaScript framework, but there are many more libraries compatible with Ender that add extra functionality. Many of the libraries available for Ender are also usable outside of Ender as stand-alone libraries.

The Jeesh is made up of the following libraries, each of these also works as a stand-alone library:

  • domReady: detects when the DOM is ready for manipulation. Provides $.domReady(callback) and $.ready(callback) methods.
  • Qwery: a small and fast CSS3-compatible selector engine. Does the work of looking up DOM elements when you call $('selector') and also provides $(elements).find('selector'), $(elements).and(elements) and $(elements).is('selector').
  • Bonzo: a DOM manipulation library, providing some of the most commonly used methods, such as $(elements).css('property', 'value'), $(elements).empty(), $(elements).after(elements||html), and many more.
  • Bean: an event manager, provides jQuery-style $(elements).bind('event', callback) and others.

The Jeesh gives you the features of these four libraries bundled into a neat package for only 11.7 kB minified and gzipped.

The Basics: Bonzo

Bonzo is a great way to start getting your head around Ender because it's so useful by itself. Let's include it in a page and do some really simple DOM manipulation with it.

<html lang="en-us">  
  <meta http-equiv="Content-type" content="text/html; charset=utf-8">
  <title>Example 1</title>
  <script src="bonzo.js"></script>
  <script id="scr">
    // the contents of *this* script,
    var scr = document.getElementById('scr').innerHTML

    // create a 

    var pre = bonzo.create('


{gfm-js-extract-pre-3}')` and we'd end up with two blocks, both responding to the click event.

###Removing Bonzo

It's possible to pull Bonzo out of the Ender build and manually stitch it back together again. Just like we used to do with our toys when we were children! (Or was that just me?)

First, our Ender build is now created with: `ender build qwery bean` (or we could run `ender remove bonzo` to remove Bonzo from the previous example's `ender.js` file).  The new `ender.js` file will contain the selector engine goodness from Qwery, and event management from Bean, but not much else.

Bonzo can be loaded separately, but we'll need some special glue to do this. In Ender parlance, this glue is called an Ender **Bridge**.

###The Ender Bridge

Ender follows the basic CommonJS Module pattern -- it sets up a simple module registry and gives each module a `module.exports` object and a `require()` method that can be used to fetch any other modules in the build. It also uses a `provide('name', module.exports)` method to insert exports into the registry with the name of your module. The exact details here aren't important and I'll cover how you can build your own Ender module in a later article, for now we just need a basic understanding of the module registry system.

Using our Qwery, Bean and Bonzo build, the file looks something like this:

text |========================================| | Ender initialisation & module registry | | (we call this the 'client library') | |========================================| | 'module.exports' setup | |


frameworks libraries date history node modules time keyboard ender responsive

Ender Roundup: tablesort.js, Moment.js, jwerty, SelectNav.js, ender-events, ender-assert, Categorizr.js, Arbiter

Posted on .

You can send in your Ender-related projects for review through our contact form or @dailyjs. Be sure to also update the Ender package list page on the Ender wiki.


tablesort.js (GitHub: tristen/tablesort, npm / Ender: tablesort) by Tristen Brown is a dependency-free sorting library for HTML tables. tablesort.js can be invoked stand-alone via new Tablesort(document.getElementById('table-id')) or $('#table-id').tablesort() method from within Ender.

Olivier Vaillancourt has written a small review of tablesort.js for use in Ender on Twitter Bootstrap tables.


Moment.js (GitHub: timrwood/moment, npm / Ender: moment) by Tim Wood is small, yet very comprehensive date and time handling library.


Moment.js was mentioned last year on DailyJS but it now has a simple Ender bridge allowing you to pack it neatly into Ender builds for use via $.ender(). Plus, it's an absolutely fantastic library for anything date/time related so it's worth mentioning again. Be sure to scan the docs to see just how much this library can do.

$.moment().add('hours', 1).fromNow(); // "1 hour ago"

// manipulate
$.moment().add('days', 7).subtract('months', 1).year(2009).hours(0).minutes(0).seconds(0);

// parse dates in different formats
var day = $.moment("12-25-1995", "MM-DD-YYYY");

var a = $.moment([2010, 1, 14, 15, 25, 50, 125]);  
a.format("dddd, MMMM Do YYYY, h:mm:ss a"); // "Sunday, February 14th 2010, 3:25:50 pm"  
a.format("ddd, hA"); // "Sun, 3PM"

// operate on different 'moment' objects
var a = $.moment([2007, 0]);  
var b = $.moment([2008, 5]);  
a.diff(b, 'years'); // 1  
a.diff(b, 'years', true); // 1.5  

The project maintainers also follow a rigorous release methodology, making great use of git branches, something that is not often found on smaller open source libraries.


jwerty (GitHub: keithamus/jwerty, Licence: MIT, npm / Ender: jwerty) by Keith Cirkel is a small keyboard event handling library which can bind, fire and assert key combination strings against elements and events.

$.key('ctrl+shift+P', function () { [...] });
$.key('⌃+⇧+P', function () { [...] });

// specify optional keys
$.key('⌃+⇧+P/⌘+⇧+P', function () { [...] });

// key sequences
$.key('↑,↑,↓,↓,←,→,←,→,B,A,↩', function () { [...] });

// pass in a selector to bind a shortcut local to that element
$.key('⌃+⇧+P/⌘+⇧+P', function () { [...] }, 'input.email', '#myForm');

// use `$.event` as a decorator, to bind events your own way
$('#myinput').bind('keydown', $.keyEvent('⌃+⇧+P/⌘+⇧+P', function () { [...] }));

// use `$.isKey` to check a key combo against a keyboard event
function (event) {  
    if ( $.isKey('⌃+⇧+P', event) ) { [...] }

// use `$.fireKey` to send keyboard events to other places
$.fireKey('enter', 'input:first-child', '#myForm');


SelectNav.js (GitHub: lukaszfiszer/selectnav.js, npm / Ender: selectnav.js) by Lukasz Fiszer is a small library that will convert your website's navigation into a <select> menu. Used together with media queries it helps you to create a space saving, responsive navigation for small screen devices. SelectNav.js is inspired by TinyNav.js for jQuery.

ender-events and ender-assert

ender-events (GitHub: amccollum/ender-events, Licence: MIT, npm / Ender: ender-events) and ender-assert (GitHub: amccollum/ender-assert, Licence: MIT, npm / Ender: ender-assert) are two packages by Andrew McCollum, previously bundled in his node-compat library. ender-events gives you an implementation of the NodeJS EventEmitter class in your browser, while ender-assert gives you a browser version of the NodeJS assert module.

Andrew also has a tiny extension to Bonzo, the DOM utility included in Ender's starter pack (The Jeesh), named ender-remove that simply triggers a 'remove' event when nodes are removed from the DOM. Which can be helpful for performing clean-up actions.


Categorizr.js (GitHub: Skookum/categorizr.js, Licence: MIT, npm / Ender: categorizr) by Dustan Kasten is a JavaScript port of the Categorizr PHP script by Brett Jankord.

Categorizr gives you $.isDesktop() $.isTablet() $.isTV() $.isMobile() methods to determine the current device.


Arbiter (GitHub: iamdustan/arbiter, Licence: MIT, npm / Ender: arbiter) also by Dustan Kasten is a tiny library for managing the HTML5 history interface via pushState(), using AJAX requests to load new content upon request.


frameworks libraries jquery plugins ender

jQuery Roundup: Declarative, jQR, Ender-Carousel, Stapes.js

Posted on .

Note: You can send your plugins and articles in for review through our contact form or @dailyjs.


Declarative (License: MIT, npm: declarative) by Alex Lawrence allows HTML to be mapped to behavioural JavaScript using mappings. The author's first example is a search form with a character counter that uses the following HTML:

<form action="/" method="POST">  
  <input id="search" name="search" type="text" maxlength="50" />
  <span data-widget-counter="target: 'search', text: '{0} characters left'"></span>
  <input type="submit">

Notice the use of data attributes to supply options to the JavaScript mapping:

  id: 'counter',
  prefix: 'data-widget-',
  types: ['counter']
  callback: function(counter, type, options) {
    var input = document.getElementById(options.target);
    var maxlength = input.getAttribute('maxlength');
    countCharacters(input, counter, maxlength);

Once a mapping has been declared, it can be mapped to the whole DOM using apply:


None of this depends on jQuery, but the author has provided examples that demonstrate jQueryUI integration. Jasmine tests and examples are included in the project's source.


jQR (GitHub: Gottox / jQR, License: GPL3) by Enno Boland is a QR Code generator for jQuery. It's similar to jquery.qrcode.js by Jerome Etienne, featured previously on DailyJS -- both use the same method name:

$('#qrcode').qrcode('Hello World');

Jerome's plugin includes qrcode.js by Kazuhiko Arase, whereas Enno's plugin is a rewrite that's influenced by Kazuhiko's original code.


Ender-Carousel example

Ender-Carousel (GitHub: nemeseri / ender-carousel, ender: ender-carousel, npm: ender-carousel) by Andras Nemeseri is a carousel plugin for Ender that's jQuery-compatible. The Ender-Carousel Basic Configuration Tutorial has sample HTML, CSS, and JavaScript, which is just $('.carousel').carousel().


Stapes.js (GitHub: hay / stapes, License: MIT) by Hay Kranen is a small JavaScript MVC framework. Like other recent takes on MVC, it's based around events and inheritance. It also works nicely with RequireJS, jQuery, and Zepto.

Stapes uses modules:

var Module = Stapes.create();

  init: function() {

Modules include data methods for getting and setting attributes:

var module = Stapes.create();

  name: 'Alex'
, title: 'Mr'

module.get('name'); // Alex  

Attributes can be removed, filtered, and updated. The author has written up full documentation and a rationale behind the project at the Stapes.js homepage.


frameworks libraries events modules ender pubsub color hyphenation

Ender Roundup: Radio.js, one.color, Hypher

Posted on .

You can send in your Ender-related projects for review through our contact form or @dailyjs. Be sure to also update the Ender package list page on the Ender wiki.


Radio.js (GitHub: uxder/Radio, Licence: MIT, npm / Ender: radio) by Scott Murphy is a simple publish / subscribe library with a well-designed chainable API. Radio.js operates through the $.radio() method from within Ender.

//create topic called changeTabEvent and subscribe myFunction
//publish to the topic changeTabEvent
//unsubscribe myFunction from the topic changeTabEvent
//do all of the above in one line via chaining

Event "channels" are created by the main radio() method.
You can then use the three main API calls to interact with the channels:
subscribe(), broadcast() and
unsubscribe(), each able to take different types and
numbers of arguments.

Radio.js will also work as a stand-alone browser library and in node.js.


one.color (GitHub: One-com/one-color, Licence: BSD, npm / Ender: onecolor) by Peter Müller and One.com is an
amazingly comprehensive color toolkit. It implicitly converts between
RGB, HSV, HSL and CMYK color spaces with or without alpha transparency.
Its API is chainable for composing, adjusting, and serializing color
values. A demo page gives you some
idea of the potential of one.color.


$.color('rgb(102, 76, 230)'). // Can parse CSS color strings
    lightness(+.2, true).     // Implicit conversion to HSL
    red(-.1).                 // Implicit conversion back to RGB
    hex();                    // "#00a6f2"

one.color will also work as a stand-alone browser library and in node.js.


Hypher (GitHub: bramstein/hypher, Licence: BSD, npm / Ender: hypher) by Bram Stein is a small hyphenation engine
compatible with Hyphenation.js
language objects.

Hypher adds soft hyphens to
text strings (Unicode: U+00AD, HTML: &#173; or &shy;) according
to language rules as defined in the patterns objects. Modern browsers
then use these soft hyphens to break words where wrapping is required,
otherwise they are invisible.

Hypher comes with a large number of
language patterns which are also available in the npm repository as
hyphenation.lang (e.g.
hyphenation.en-us or hyphenation.fr). Simply
include hypher and at least one language pattern in your
Ender build.

// generates 'Hy|phen|ation is use|ful when cen|ter jus|ti|fy|ing a text.'
// where `|` is a soft hyphen
$('<p>Hyphenation is useful when center justifying a text.</p>')

Hypher is also available as a jQuery plugin and will work as a stand-alone
browser library and in node.js.

Tidbits and updates

Some minor notable items since the last Roundup:

Bonzo goes 1.0.0

Bonzo, the DOM manipulation library included in The Jeesh, has received a lot of minor fixes this week and its test suite has been
significantly expanded, so much that a bump to 1.0.0 seemed appropriate.

Minor Qwery update

Qwery, the selector engine included in The Jeesh had some minor performance improvements, particularly for IE8,
and can now be configured to turn off use of native
querySelectorAll if required:
$.configure({ useNativeQSA: false }).

Bean does better delegation

Bean, the event manager included in The Jeesh, has received some delegation-love, fixing bugs related to
clone() and erroneous event.currentTarget

Bean is also likely to see a change in the implementation of
on() that will make it (mostly) compatible with the
implementations in Prototype,
jQuery and Zepto. Further details are available on GitHub.

Ender via CDN

After the flurry of recent activity on core Ender modules,
Dustin Diaz has updated the The Jeesh and a more bulky Ender build on S3 this week, so is these builds suit your
needs then point your script tag to one of these CloudFront URLs:

The Jeesh (Qwery, Bonzo, Bean, domReady)


Jeesh++ (Qwery, Bonzo, Bean, domReady, Reqwest, Morpheus, Valentine, Bowser, $script.js)


Twitter's Bootstrap for Ender

Along with the release of Bootstrap
, an Ender compatible version
is now available on npm. Unlike the v1.x port, this new version makes
each plugin available separately so you only need to include the ones
you intend to use in your Ender build.

With all plugins installed, a minimal Ender build for full Bootstrap
functionality comes in at a little under half the size of the equivalent
jQuery Bootstrap.

Further details available on the new
ender-bootstrap repository.


frameworks libraries events templating dom modules ender dnd selectorengines css4

Ender Roundup: Swig, Traversty, NWMatcher, Ender-Overlay, Dagron

Posted on .

You can send in your Ender-related projects for review through our contact form or @dailyjs. Be sure to also update the Ender package list page on the Ender wiki.

Swig for Ender

Swig for Ender (npm / Ender: ender-swig), by Nicolas Chambrier, is a wrapper and build script for Swig, by Paul Armstrong. Swig is a fast template engine inspired by Django.

When included in an Ender build you get a $.swig object and a $.render method that lets you render templates from <script> tags by ID.

<script type="text/html" id="tpl">  
Hello, {{ "{{ name " }}}}.  

<script type="text/javascript">  
$.render('tpl', {"name": "dude"}) // →  "Hello, dude."

Swig also includes support for template inheritance:

{% raw %}
<script type="text/html" id="parent">  
Hello, {% block name %}John Doe{% endblock %}.  
<script type="text/html" id="child">  
{% extends 'parent' %}
{% block name %}dude{% endblock %}

<script type="text/javascript">  
$.render('child') // →  "Hello, dude."
{% endraw %}

Swig depends on Underscore.js, which will be automatically included in your Ender build.

Another popular templating library for Ender is Wings (npm / Ender: wings) by Andrew McCollum, based on Mustache.


Traversty (npm / Ender: traversty), by Rod Vagg, is a simple DOM traversal utility heavily inspired by Prototype's "DOM traversal toolkit". You get up(), down(), next() and previous() with optional selector and index arguments, all in a multi-element environment (jQuery-like rather than Prototype's single-element implementation).

In their simplest form, up(), down(), next() and previous() let you move around the DOM by single-element steps but can be used like an optionally indexed find() in all four directions:

$('#root > ul') // can match and operate on multiple elements
  .down(0).css('color', 'red')
  .next('li', 1).css('color', 'green')
  .next().down('li', 2).css('color', 'blue')
  .next().down().css('color', 'yellow')
  .up(2).next().css('color', 'purple');

Traversty has no dependencies but will detect the presence of a selector engine if included in the Ender build (officially supports Qwery, Sel Sizzle and NWMatcher). Without a selector engine, Traversty will rely on native querySelectorAll() and the various vendor-prefixed native matchesSelector() implementations (available everywhere post-IE8).

Traversty can also be used as a stand-alone library:



NWMatcher (npm / Ender: nwmatcher), by Diego Perini is a battle-hardened selector engine with a strong focus on standards compatibility. It's consistently fast across browsers and has continuing support for some very old browsers. NWMatcher became a popular alternative selector engine for Prototype users when the selector engine code was modularised in version 1.7. It continues to have a strong following, particularly amongst purists who appreciate NWMatcher's close adherence to W3C standards.

NWMatcher now has Ender support and is in npm so can be easily included in your Ender builds: ender build nwmatcher undersore bonzo bean

Some of NWMatcher's advanced features are supported directly via Ender:

// adjust NWMatcher's internals
$.configure({ USE_QSAPI: false, VERBOSITY: false });

// a collection containing the first match only, works like
// querySelector() and halts processing upon first match

// just like calling $('div', root) but will trigger a callback
// function on each match found
$.select('div', root, callback);

// does at least one element in the current collection match
// the given selector?

// alias for .match()

// a new collection of child elements matching the given selector

// a new collection that includes the original collection and
// additional elements matching the given selector

As with all Ender modules, the original library can be accessed via require('nwmatcher'), this gives you the same object as NW.Dom when running outside of Ender.

NWMatcher has no dependencies and can be used as a stand-alone library.


Ender-Overlay (npm / Ender: ender-overlay), by Andras Nemeseri is a highly configurable module for building dialogs, galleries, lightboxes etc.

<a id="trigger-vimeo" class="thumbs"><img src="http://www.samholdren.com/vimeo-Logo2.png" alt="Vimeo HTML5 Embed" width="100" height="100"></a>

<div id="overlay-vimeo" class="ender-overlay overlay-vimeo">  
  <a class="close close-button" title="Close">&#9747;</a>
  <iframe src="http://player.vimeo.com/video/12132621?title=0&byline=0&portrait=0" width="601" height="338" frameborder="0" webkitAllowFullScreen allowFullScreen></iframe>

<script type="text/javascript">  
$(document).ready(function() {
  $("#overlay-vimeo").overlay({ trigger: "#trigger-vimeo" });


Andras has put together a tutorial, demos and documentation covering all options, events and methods on the Ender-Overlay page.

Ender-Overlay depends on the Jeesh (Ender's official starter pack) and Morpheus for animation.


Dagron (npm / Ender: dagron), by Dustin Diaz, is a very simple interface to HTML5 drag and droppables.

    // all options are 'optional'
    handle: 'div.handle'
  , target: 'div.droptarget'
  , start: function(el) {} // el is the item you started dragging
  , drag: function(el) {} // el is dragged element
  , drop: function(el) {} // el is the target the dragged item was dropped on
  , enter: function(el) {} // el is the element target you entered into
  , leave: function(el) {} // el is the item left from
  , end: function(el) {} // el is the element you stopped dragging

Dagron depends on Qwery and Bean (both part of the Jeesh).


There were a couple of notable updates to Ender modules recently:


Bean, by Jacob Thornton, is Ender's default event handling library. It received a major internal overhaul and a version bump to 0.4.x. Bean has a new internal registry for storing event handler data and it no longer relies on storing an ID on your DOM elements or your JavaScript objects. There have been some small fixes and optimisations and the inclusion of a new event.stop() method that invokes both event.preventDefault() and event.stopPropagation(), but otherwise the external API remains largely untouched.

Reqwest gets jQuery compatibility

Reqwest, by Dustin Diaz, is Ender's native Ajax library, giving you a jQuery-like $.ajax() method. There are some differences in options between Reqwest and jQuery / Zepto which has caused some pain for jQuery users migrating to Ender and for libraries designed for jQuery integration, such as Backbone.js. In particular, jQuery uses type where Reqwest uses method, jQuery uses dataType where Reqwest uses type. Thankfully, Reqwest now has a compat mode. Calling $.ajax.compat() gives you access to the same option names as jQuery.

You can also install jQuery / Zepto mode as default in your projects with: $.ajax.compat && $.ender({ ajax: $.ajax.compat });

Full details can be found in the Reqwest README.

Sel gets CSS4

Sel, by Andrew McCollum, a selector engine for Ender, is one of the first selector engines to receive some CSS4 love. Working from the latest working draft, Andrew has enabled some excellent additions to Sel's query syntax:

/* subject overriding, was '$div .box' in a previous CSS4 draft,
   returns 'div' rather than '.box' */ 
div! .box

/* id references, 'input' who's ID matches 'label's 'for' attribute */
label /for/ input

/* case insensitive attribute matching */
[attr = "val" i]

/* :nth-match and :nth-last-match to match against sub-selectors */
div:nth-match(3 of .box)

/* links who's target absolute URI matches the current document's URI,
   arguments specify the degree of locality */

/* :column */

/* :nth-column and :nth-last-column */

The subject identifier (!) in CSS4 is going to be particularly useful for JavaScripters.