Writing jQuery Plugins: Utilize and Learn from Existing Plugin Patterns

Once you have the basics of plugin development down and want to expand your horizons to include some very advanced options for plugin development, another, more recent, resource to look at is Addy Osmani’s article “Essential jQuery Plugin Patterns” (http://coding.smashingmagazine .com/2011/10/11/essential-jquery-plugin-patterns/) and the associated Github repository (https://github.com/addyosmani/jquery-plugin-patterns). In it, Addy presents a well- researched series of starting points for plugin development. The options range from a simple example (shown in the next code sample) that will already look pretty familiar to you, to advanced options supporting module patterns like RequireJS, Asynchronous Module Definition (AMD), and CommonJS.

As both a simple starting point for your own plugin code and as a learning resource, the article and associated repository are essential reading. The following code example from https:// github.com/addyosmani/jquery-plugin-patterns/blob/master/jquery.basic.plugin- boilerplate.js shows one such piece of boilerplate code along with the associated comments. As you can see, a lot of thought went into the pattern itself and each line is given a careful explanation. Some of the options may be too advanced for you right at the beginning of your exploration of plugin development, but for medium to advanced plugin developers, it’s an extraordinary resource.


* jQuery lightweight plugin boilerplate

* Original author: @ajpiano

* Further changes, comments: @addyosmani

* Licensed under the MIT license


// the semicolon before the function invocation is a safety

// net against concatenated scripts and/or other plugins

// that are not closed properly.

;(function ( $, window, document, undefined ) {

// undefined is used here as the undefined global

// variable in ECMAScript 3 and is mutable (i.e. it can

// be changed by someone else). undefined isn’t really

// being passed in so we can ensure that its value is

// truly undefined. In ES5, undefined can no longer be

// modified.

// window and document are passed through as local

// variables rather than as globals, because this (slightly)

// quickens the resolution process and can be more

// efficiently minified (especially when both are

// regularly referenced in your plugin).

// Create the defaults once var pluginName = ‘defaultPluginName’,

defaults = {

propertyName: “value”


// The actual plugin constructor

function Plugin( element, options ) {

this.element = element;

// jQuery has an extend method that merges the

// contents of two or more objects, storing the

// result in the first object. The first object

// is generally empty because we don’t want to alter

// the default options for future instances of the plugin

this.options = $.extend( {}, defaults, options) ;

this._defaults = defaults;

this._name = pluginName;



Plugin.prototype.init = function () {

// Place initialization logic here

// You already have access to the DOM element and

// the options via the instance, e.g. this.element

// and this.options


// A really lightweight plugin wrapper around the constructor,

// preventing against multiple instantiations

$.fn[pluginName] = function ( options ) {

return this.each(function () {

if (!$.data(this, ‘plugin_’ + pluginName)) {

$.data(this, ‘plugin_’ + pluginName,

new Plugin( this, options ));




})( jQuery, window, document );

Code snippet is from jquery.basic.plugin-boilerplate.js

As you can see, this boilerplate code encapsulates many of the best practices illustrated in this chapter and adds a couple of important enhancements, such as preventing multiple plugin instantiations looking for the presence of the plugin in $.data.

You can’t go wrong starting with such a solid foundation, and because the project is on Github, it will benefit from the ongoing eyes and tweaking offered up by the larger jQuery community.

Source: Otero Cesar, Rob Larsen (2012), Professional jQuery, John Wiley & Sons, Inc

Leave a Reply

Your email address will not be published. Required fields are marked *