At SXSW this year, someone predicted that jQuery would not exist – at least, as we know it today – in two years. It was kind of one of those things where your mouth goes, “What?! That’s ridiculous!” while your brain goes, “Whoa, of course.” Obviously jQuery continues to improve, but in terms of the stuff that people desperately needed it for, it seems to me it’s been stable for some time. When I began my job last week I found out that there are a few parts of the site we’re in the process of upgrading from jQuery 1.3.2 to 1.6.2. I asked why we weren’t upgrading to the latest version. Part of the response was that the upgrade had begun when 1.6.whatever was the latest version. The other part was that the difference between the slightly-older and most-current versions didn’t seem compelling enough to justify starting over.
The idea of an optional jQuery upgrade is somewhat fascinating to me. People got stuck on 1.3, that’s understandable. There was a legitimate risk of things breaking, and how many sites had a full suite of regression tests at that point? But when did it become an option to not upgrade for lack of perceived value instead of threat of destruction? I don’t know, but I feel like it was recently. And although I think the changes since jQuery 1.6.2 are pretty fucking slick, I have to agree that the world isn’t going to end if we don’t upgrade immediately, or even if we never do.
My impression is that we’re in a brief window right now where jQuery still has a brilliant team of people working on it, but is stable from the perspective of most users. The most advanced might care deeply about event delegation and the features of deferreds, but someone who merely wants a reliable cross-browser click handler probably doesn’t give a shit. And they no longer have to. jQuery and others solved the problem so well that we can all safely forget there was a problem. Unfortunately, I think that means once there are no more improvements to make to event handling and no more features to add to deferreds, the brilliant team will begin moving on to other projects. I think the same will happen to Backbone, and Socket.IO, and whatever goofy-ass transpiler is cool right now. The things we had to do manually moved into libraries and tools, and the things we needed libraries and tools for are moving into the browser. It’s just a matter of time.
So if you agree that the sky is very slowly falling, what do you do about it? Two things. First, you begin to insulate yourself. Second, you take an active role in making sure the things you need most survive as open-source software and don’t get tied to larger projects whose futures may not include the relevance they enjoy now.
I’ve been about insulating yourself from plugins for some time. That’s cause I worked for a company that had three different dialog plugins in use and getting them standardized was a pain in the ass. When one was discovered to lack some important feature, no problem, someone would download a different one, implement it on a new page with new site-wide CSS to make it appear similar to the old one, and now there would be two ways of creating a dialog. Clearly that’s fucking stupid. But many places settle for standardizing on one dialog plugin, or one UI library that contains a dialog widget, and leaving it at that. I think you should go a step further. Don’t rely on developers (present and future) to know that you use jQuery UI for everything except this one super-special dialog. Instead create a library namespaced with your site or company’s name and put everything under there. I don’t give a shit if
CoolCo.dialog has a signature that matches the plugin’s exactly and contains only one line where you pass the plugin its arguments. Wrap everything up, put it in the same namespace.
Once all your shit is insulated from the tools you’re using, begin looking at the methods you rely on. Are you using jQuery selectors but only targeting cutting-edge browsers? Maybe that’s something you could replace with
querySelectorAll. Is that necessary? Will it everything super fast? Is there a big risk that jQuery selectors suddenly become monstrously inefficient? Probably not. But, on the other hand, it protects you from Bizarro John Resig. Bizarro John Resig is a theoretical maintainer of the jQuery project who will emerge in the post-apocalyptic future of web programming and decide to rewrite the library to optimize it for WebGL, and remove everything else. When that happens, you will be glad you’re using
CoolCo.qsa instead of the dollar sign.
To put it another way, there’s excellent broadly applicable code in jQuery now that – for the things the library’s known for – gets the job done remarkably well. Once jQuery reaches a point where you’re very excited about the features a segment of the code provides, freeze that method yourself by copying it into your code. When a change to that feature that you need comes along, swap the code out. If you’ve insulated yourself well, hopefully the way your library uses the functionality doesn’t have to change.
So in addition to building a fortress to protect you from the giant robots, there was a second point, and this is about avoiding copying and pasting wherever possible. Let’s go back to dialogs. You know what’s awesome about jQuery UI? It’s modular. If you just want dialogs, you can just get dialogs. We need everyone to do that. We need the pieces. Instead of downloading a package of everything including the kitchen sink we need modules. I think about this a lot when working on node stuff. Node lacks many things that are very monolithic. A lot of people are annoyed by this. The more I think about it, the more I like it. Your application should be written to run your application. There’s a new version of node? Of course there is, it’s Tuesday. Does it give you anything you need? No? Fuck it. Wait until you have a reason to move. More importantly, if a project progresses in such a way that it’s introducing dependencies that aren’t relevant for your app, consider whether it’s appropriate for you to maintain a fork without the dependencies that provides a subset of the functionality.