Before we get started, I should mention that whilst I have an involvement in the jQuery Project, I subscribe to the notion of using the best tool for the job at the end of the day, whether that happens to be an established library/toolkit/framework (eg. jQuery, Dojo) or an alternative micro-solution. Hopefully this post will come across as balanced in that respect.
Why consider micro-frameworks?
It's no secret that with each subsequent release, well-established libraries, frameworks and toolkits increase in size and this has some developers questioning whether the entire stack of functionality provided is required for the average site or project. We live in an age where performance and page-load time are constantly under scrutiny and thus, a developer couldn't be blamed for attempting to cut down unused code from their site's overall load.
The reality is that you may only wish to use a subset of features offered in a library like jQuery (eg. selection, animation) but may not require support for ajax, DOM-associated data storage, deferreds and others. The library may also not provide everything your project needs (it's naive to think it ever would), however we can appreciate a developer asking whether that 30KB+ download of the library could be replaced with something significantly more modular that does cover more of their own needs.
This is an area where using micro-frameworks can potentially offer the greatest benefit to a project (especially where mobile is specifically targeted).
Thomas Fuchs has been attempting to make developers more aware of micro-frameworks through efforts such as microjs.com (which you should check out) and there certainly appears to be enough interest in modularized frameworks for a broader discussion on micro-frameworks to keep going.
The pros and cons of micro-frameworks
Let's now take a look at what I consider the pros and cons of micro-frameworks:
- Micro-frameworks generally encourage building small, tight and loosely coupled components that can then be assembled by the developer.
- In many of them, a focus on solving specific problems means that a great deal of manual optimization must be done to ensure code is as DRY and focused as possible. The result of this is that you're unlikely to have large chunks of code in the framework with solutions to problems that won't be utilized.
- All-encompassing frameworks and libraries have a problem: if they don't support the behaviour you require, you'll either need to find a solution around the walls of the framework, write in what's missing yourself or you may be out of luck. Using jQuery as an example, one could argue that because modular builds are not available, a developer wishing to use it would require the entire library (including those parts they don’t wish to use). They would then also need any additional micro-frameworks to be padded on top followed by their application logic, rather than having a modular solution *just* containing solutions to what they need. That said, bear in mind that current modular solutions such as Ender have had issues trying to get completely independent libraries working together. It’s tricky smoothing out the rough parts of mixed micro-frameworks but this situation may improve with time.
- As micro-frameworks usually attempt to solve specific problems rather than larger concerns, a custom modular library could be put together consisting of a few <5-8KB micro-frameworks. Whilst size is something often promoted as a reason for using such frameworks, it’s very important to note that size is an unsophisticated way of selecting frameworks. It isn’t an indication of code quality, functionality or just how appropriate it is for what you’re trying to solve. Size may not matter, but modularity is, however, key. This is in my opinion the biggest draw towards using micro-frameworks as opposed to larger libraries.
- Modular code could very well be the future with micro-frameworks being capable of easily plugging together as needed using a common unified API. Something both modular, well documented and cross-browser would be ideal for developers concerned about these issues.
- Ease of understanding: some micro-frameworks contain significantly less code than their library/toolkit brethren and whilst this may mean fewer features, they offer an unparalleled opportunity to understand how a minimalist implementation of a solution to a problem might be approached. A very important note to bear in mind here however is that this is certainly not always the case - there are framework developers that place more emphasis on file-size over functionality, readability and compatibility and if a micro-framework jumps on the pre-minification bandwagon, it can mean that this benefit is lost. Ideally, minification should always be left to your build-process to handle so that your code is as kept as readable as possible.
- Larger libraries have a number of benefits which not all micro-frameworks may be able to provide.
- They typically offer a greater deal of cross-browser coverage, due to the number of browser quirks and edge-bases that are worked around beneath the bonnet. Micro-frameworks are not always able to offer this due to the fact that the codebase needs to be kept as minimal as possible (many micro-frameworks are also quite young, so there could still be a significant number of issues yet to be discovered). In this respect, there may be a greater risk of you or your team having to work on patching issues with the framework itself.
- They're generally more heavily tested. Each feature and major change in well-established solutions requires unit tests and the entire library test suite to pass in order for the changes to make it into a final release. Whilst some micro-frameworks do thoroughly test their solutions (and should be commended for it), it's important to be wary of those that do not (sometimes just due to lack of time by the project owner). Well-tested production-ready code is only as good as the components helping to provide it's structure and functionality.
- If modules aren't going to be interoperable, we may well see a significant amount of redundancy because none of them will be dependent on each other. The issue here is that the separation of concerns/focus may well result in much duplication on 'core' level helpers.
- Your modular framework may grow. At the moment one of the most compelling reasons being pushed to use micro-frameworks is size. Your codebase (and it's requirements) may well grow with time and one has to ask oneself just how long it may take before a framework composed of many different modules might well surpass the size of a library.
- Some micro-frameworks (certainly not all) are what could be considered one-man operations. Whilst a single individual (with or without community contributed assistance) may well be able to maintain a framework, bug tracker and docs, the reality is that were they to move on, someone else would need to be found who could take over the day to day handling of the project.This isn't the case with larger libraries as they typically don't rely on a single individual, but rather a larger group of developers to maintain the codebase and handling of the project.
- Centralized documentation and bug-tracking is often not possible with micro-frameworks. When using 5-10 solutions to create a custom modularized framework of your own, each component project is likely to have it's own repository, it's own documentation and each of these will need to be checked separately should you require assistance when writing code. Whilst this could be considered a moot point, it is one that is relevant when considering the amount of time available to actually develop a project.
- Outside of jQuery, other libraries and frameworks such as Dojo, MooTools and YUI already heavily emphasize modularity and code reuse, allowing you to use only what you need. These solutions are mature, have been tested and used in production and may offer a more reliable alternative for those searching for modular solutions than something custom based on micro-frameworks.
So, should you consider dropping that large library for a micro-framework?
As the majority of developers I've spoken to regarding micro-frameworks have brought up jQuery's filesize as their reasons for considering a switch to the micro-approach, I'll address a few concerns here. Bear in mind this is my personal opinion and may differ with those held by other members of the community:
By selecting an option such as Ender’s Jeesh starter-pack (a fraction of jQuery's 30KB), you actually may lose quite a significant amount of cross-browser stability and consistency. Edge-cases actually account for some of the smaller quantities of code in jQuery core, but it’s smoothing out issues with WebKit and IE that are most highly catered for behind the scenes. I’m not attempting to finger-point Ender out at all, but it is essential you’re aware of what you may be gaining vs what you may be losing.
In addition (and something quite important to note) most of what we've used micro-frameworks for in the past are features which jQuery doesn't (and may well never) provide in the future: MVC helpers, browser state management/routing, pub/sub, baked-in templating, cross-browser storage, (a)synchronous script loading and more.
Remember that jQuery's biggest strengths lie in being the best cross-browser DOM-manipulation and selection option out there at the moment. It's mature and for the most part, reliable. Whilst I know developers would like something more modular, John Resig has said on multiple occasions that a truly modular version of the library would be very difficult to put together and likely won't be on the cards anytime soon.
With this in mind, if you absolutely know what you're doing (and what to look for) you can of course select a more modular-suitable substitute, but you should heavily test whatever you replace it with to ensure it's on par with both Sizzle and the rest of the library's capabilities you'll require.
When deciding on which option works best for you, bear in mind both your current and future needs, level of browser compatibility required and the level of confidence you have in deploying a custom baked solution to production.
At the end of the day, it's up to each individual developer to make a judgement call here on which option makes the most sense for them (and their team) will ultimately depend on which solution satisfies the majority of your needs the best.