Introduction

I've been developing and studying plugins, particularly in jQuery for quite sometime and through this process I have learned a lot about what works and what doesn't work. There are a ton of great plugins out there that look great on the surface but are sometimes very frustrating to work with behind the scenes. So many plugins if only had a little extra effort could be taken from good to great and become much more widely used.

These are some simple tips that I have put together that will help any developer write truly great plugins. There are some things that may not seem quite as obvious at first, but they are there not only to develop your jQuery plugins, but to help maintain and expand on them in the future as well.

It is also important to note that having a solid structure and guideline to follow for you plugin speeds up development significantly as it takes away any time required to think about how you should start your project. You will already know and will only need to write the core code of your plugin and not worry about any of the other details.

1. Plugins Should Work Out of the Box

This is my biggest frustration when using plugins out there so I have made it the first point. Your plugin should just work, there should be no extra setup or structure to define. There should at the minimum be a basic default that just works and should not require anything more than an initialization.

$("#container").wTooltip();

A good example would be a jQuery slideshow plugin that has an interface for slides and a next/prev button. I've seen plugins that will ask you to set up a div with a proper id and class and then ask you to reference it through the plugin function. Things like this should be built in directly and should be provided as options that can be toggled on or off.

2. Always Provide Default Settings

It will be quite rare that your plugin will contain absolutely no configurable settings. This follows from the first point as you should always try to find as many settings as you can and provide a set of defaults for them as well. This will definitely increase the chances of any developer using your plugin and increases that chance that they will spread the word about it.

var defaultSettings = { mode : 'Pencil', lineWidthMin : '0', lineWidthMax : '10', lineWidth : '2' }; settings = $.extend({}, defaultSettings, settings || {});

The code above is the standard way to set your default settings and extend them with any settings developers may pass in.

3. Keep All Naming Unique

When creating your plugin you should always be mindful of keeping any reference to the plugin absolutely unique. This goes for classes, ids and the plugins name itself. This requires absolutely no extra effort and will ensure that you avoid any conflicts with existing JavaScript and CSS code.

$("#container").tooltip(); //bad $("#container").wTooltip(); //good

In the above example we keep the name unique for our plugin by prepending it with a "w" to differentiate it from any generic names that might otherwise exist. I also follow this unique naming convention with the CSS and will make sure even generic terms like "tab" or "holder" all contain the keyword.

_wPaint_button _wPaint_holder

I also like to add the underscore just to make sure there is no chance of nay id or class name conflicts, giving me more confidence that my jQuery plugin will succeed.

4. The Standard Plugin Layout in a Nutshell

This is a pretty standard piece of jQuery code that you will see most good plugins having, it has all the important pieces you will need for developing, maintaining and updating your plugin. Following a structure takes away a lot of the guess work and lets you focus on developing the plugin. You can take a look at my jQuery Tooltip Plugin code, which is one of my smaller code bases for a better idea of how this all works together.

var defaultSettings = { //settings }; $.fn.wPaint = function(settings) { //check for setters/getters return this.each(function() { var elem = $(this); //run some code here elem.data("_wPaint", wPaint); } //classes/prototyping }

There are five key points to note here:

Default settings go outside of the plugin, it does not need to be instantiated each time. Setters and getters aren't always required but should be checked for before running the main each loop. Return each element to not disrupt the jQuery method chaining flow. Store any data for the element using .data(), we may need this later for setters and getters. Finally setup any Classes/Prototypes outside and after the main loop.

5. Keep Your Code Organized

Although this one seems quite obvious I will quickly run through it as I have seen some odd setups in far too many plugins. It's always a good idea to keep a simple file structure for your files that is self explanatory.

./images/ ./includes/ ./themes/ ./wPaint.js ./wPaint.min.js ./wPaint.css ./wPaint.min.css

It's quite clear with the following setup, which files need to be included and where I can find other plugin files or jQuery libraries should I need to take a look at them.

6. Use Class Prototyping

This is a pretty big topic on it's own so I will only briefly mention it here. Basically there are two main reasons for prototyping your functions.

Not having to instantiate a separate copy of each method is much more efficient and runs faster. It saves a ton of memory by only having references to each object method and not having a copy of each one.

function Canvas(settings) { this.canvas = null; this.ctx = null; } Canvas.prototype = { generate: function() { //generate code } }

It also serves to organize your code and makes it much more reusable. In the above example only the Canvas object gets instantiated for each new object while the prototyped functions are only referenced.

7. Provide Setters and Getters

Providing setters and getters is not a requirement but I find it's a good option to provide your developers should they need it. All we're doing here is allowing modifications to the plugin after it has been called. The most basic setup follows:

if(typeof option === 'object'){ settings = option; }else if(typeof option === 'string'){ if( this.data('_wPaint_canvas') && defaultSettings[option] !== undefined ){ var canvas = this.data('_wPaint_canvas'); if(settings){ canvas.settings[option] = settings; return true; }else{ return canvas.settings[option]; } }else return false; }

All we're doing here is checking if an option is set rather than some settings. If two parameters are provided it means we are setting, if one parameter is set it means we are requesting the specified option.

8. Test in All Browsers

This is absolutely crucial for the survival of your plugin. Developers may not catch glitches in your code, but their users most certainly will and if there are a lot of complaints that lead back to your plugin it will simply be replaced. For instance in my jQuery Color Picker Plugin I found a few small bugs that totally made my plugin unusable in ie7, that just required a simple fix with floats since ie7 does not support "inline-block" elements.

This step can always be tiring as after completing a plugin you feel you just want to launch it. Make sure you always hold back on this urge and spend the extra day to test your plugin thoroughly with as many scenarios as you can think of. This will not only fix up any simple bugs but also may shine some light on some simple improvements.

9. Packaging for Release

Once your plugin is all polished and ready for release take the time to do the next three simple steps.

Write some documentation for the trickier parts, not only for other developers that may be looking at your code but for yourself as well. Version your plugin either by the file names or in the documentation somewhere. It doesn't matter where as long as developers can see what version they are using and check for updates. Finally provide minified versions of your code, this only takes a few minutes and adding it will make developers using your plugin happy and coming back for more.

10. Upload Your Plugin

Sometimes it's the simple steps that can really make a difference, in the end the developers will make or break your jQuery plugin so make sure you keep them as happy as possible.

There are plenty of services out there for this, but two I prefer are Github and Google code.

You man not always want to upload your jQuery plugins for public use, especially if it's an internal project for work, but likewise keep your plugins in their own repository and outside of the main codebase. This ensures your plugins get maintained with proper versioning and documentation.

However if your plugin is indeed for public use, services as the above mentioned Github and Google code are fantastic as they provide areas for issue reporting, activity feeds and download counters.

This lets you interact with the users of your plugin to see how well your plugin is doing from a total downloads point of view. These services are extremely easy to setup and provide a lot of value.

Conclusion

Following these tips should pretty much cover the core of your jQuery plugin lifecycle. It also provides a more standard format for you to follow as well as providing a familiar strucure that developers are used to. Wheter you are developing plugins for fun or profesionally the more your plugin gets used the more gratifying it feels.