We've breaked it down into three sections:
- Paradox of Choice - too many libraries doing the same thing
- Propensity for Jumping on Bandwagons - many developers throw out existing (tested) frameworks and adopt the new framework without understanding their merits
Rapid Introduction of New Specifications
The Rise of NodeJS
HTML5 is the fifth (duh!) and current implementation of the HTML markup language (yes, we know we're comparing a programming language with a markup language). Since HTML was initially released in 1993, in its 23 years of existence, there has only been 5 versions - 1993 (v1), 1995 (v2), 1997 (v3, v4), 2014 (v5).
Python, a general-purpose programming language, was released in 1991 and has had only 3 major (and 17 minor) versions.
PHP, arguably the most popular web programming language (I call it the gateway language), was released in 1995 and has had 6 major versions and 17 minor versions.
In contrast, NodeJS, which was first released in 2011, has had (depending on how you count it) 6 major and 40 minor versions.
But it also made the evolution of the language much more rapid - ECMA is now planning to roll out a new set of ECMAScript specifications every year, and NodeJS has released 3 major versions already in the past 12 months.
The Problem with Rapid Evolution
Each time a new ECMAScript specification appears, the follow list of problems becomes inevitable:
Lack of backwards-compatibility - Developers using the new specification needs to ensure that their new codebase is backwards-compatible with older browsers/runtimes. This might not sound too complicated - you just add a shim/polyfill and forget about backwards-compatibility!
If only it was that easy! For ES5, there were one standout shim - the aptly-named es5-shim. For ECMAScript 2015 (ES6), there is Babel - a suite of tools which includes an ECMAScript 2015 to ES5 compiler, polyfills amongst others.
es5-shim is a shim, which means intercepts existing API calls and provide a new or alternative implementation. A polyfill detects if an API is present, and if not, provide an implementation for it. A compiler (in our case) transforms code written in the new specification (e.g. ECMAScript 2015), to code which conforms to a previous specification (ES5).
By the time the new features are supported, the next specification would probably have already overtaken over as the newer standard.
Lack of guidelines - A specification is just that - it specifies what you can do, but it doesn't show you in what situation you should use it, or how an over application would look like with the new specification.
For beginners, they'll often refer to tutorials; but when some tutorials use specification X, and others use Y, it can be very confusing.
Just look at this Stack Overflow question to see how confusing a syntax change can be when React tried to be more ECMAScript 2015-conforming.
As we said, these problems are necessary for the evolution of a language. However, when it occurs at such a high pace, there is no stability - code which conforms to the latest (best) standards a year ago is now seen as out-dated.
And these changes does not only affect the language, it affects the libraries, frameworks and applications which are built on that language.
In the case of Meteor
We have been working with Meteor for about 2 years now, and since version 1.0.0, there have been major changes, most notably with React, native npm support and ECMAScript 2015.
In February 2015 (still 1.0.0), if you want to use ECMAScript 2015, you need to install the
grigio:babel package from Atmosphere - Meteor's package manager.
Then in September 2015, Meteor 1.2.0 was introduced, which supported ECMAScript 2015 but requires the installation of the
ecmascript package. It did not, however, support all ECMAScript 2015 features.
Meteor 1.2.0 was meant to be backwards-compatible, which means you can write ECMAScript 2015 for new components while leaving the old code just as it is (I would never recommend this as consistency in a code base is more important that ensuring it follows the latest specifications).
In March 2015, Meteor 1.3.0 was released, and with it came the support of ES6 modules - or the
So in just over a year, it went from writing traditional ES5, to using Babel to write ECMAScript 6 that is compiled back to ES5, then to using the
ecmascript package which did not support all ECMAScript 2015 features, to finally 'full' support.
It is impossible to update your entire codebase each time a new standard comes out. And if you work on multiple projects at the same time (like we do), mentally switching from Meteor 1.0 to 1.2 and then to 1.3+ is time-consuming and confusing.
The Paradox of Choice
Whether it'd be ego, or disagreements, there are many libraries and frameworks out there which essentially perform the same tasks (even though all of them claim they do it better). This leaves new developers with having to research X vs Y vs Z before even a single line of code is written.
Here are some examples:
- Utility library - lodash, underscore
- Continuous Integration - Travis, Jenkins, Hudson, Bamboo, CircleCI
- Frontend UI Frameworks - Bootstrap, Foundation, Semantic UI, uikit, Pure, KendoUI (Requires a purchase but looks amazing)
This is, of course, an essential part of the evolution of a language (or library, or framework, or anything really) - improvements are proposed, some are tested, those which prove to be popular are adopted.
But when, in the case of Continuous Integration tools, all of them seems equal in terms of popularity, and there is no stand-out winner, you can commit to using a tool which, in 2-3 years, may become obsolete.
Developers have to Google X vs Y for everything before anything is written - that's a real issue.
Propensity for Jumping on Bandwagons
When a new library or framework comes out, there's always some hype - that much is expected. But I get the feeling that developers always thinks that the grass is always greener on the other side and that framework X is better than framework Y.
So when a new framework comes out every few months, they're often heralded as the next-best-thing, and we should all abandon the obsolete framework we are using and use the new one. This leads to instability in the code and high cost of maintenance.
Let's take a look at some front-end frameworks.
I remember around the end of 2013 to early 2014, ember.js was reaching the peak of its popularity - it was all the hype.
And then in mid-2015, Angular became really popular.
And now, React's popularity is still rising and is seen as the new best thing.
But it still doesn't end there, new kids on the block - Aurelia and vue.js has been making the rounds.
This is very common - with Meteor, Iron Router is a perfectly fine router, but then Flow Router was introduced by a well-known developer and almost everyone started using Flow Router instead, without understanding why.
But maybe this is not a recent thing. Back in 2008, Jeff Atwood (of Stack Overflow fame) described those developers which jump on the new and shiny things as Magpie developers.
Don't feel inadequate if you aren't lining your nest with the shiniest, newest things possible. Who cares what technology you use, as long as it works, and both you and your users are happy with it?
Be the Early Majority
But if everyone is jumping on, you must jump on also - because the new libraries (which will become standard later) will be written in this new language.
But many libraries do not survive the initial hype, and so what I recommend developers do is to jump on in the early-majority stage:
Graph taken from http://www.jamasoftware.com/blog/5-tips-software-adoption/
This way, you're still ahead of most people, whilst the innovators and early adopters have already gone through the frustrating and depressing stages of figuring out what works and what doesn't, refactoring the codebase to be production-ready, writing the most commonly-used libraries - you just stroll in take advantage of other people's work!
That's why it is extremely important for you to have time to update yourself, either during work hours (if your employers are decent), or during your own free time.
Most of all, try out the different tools and make a judgement for yourself of which tools fit your style, and understand that there are merits with each tool, so don't use just one stack for everything.
Remember, with every framework, there is a 100% chance that someone will write a negative critic of it, which often sounds like:
- Why I stopped using X (Grunt, Spring, Angular, .NET)
- Why X is a broken language (See this, for the lol's)
- The Problem with X (Angular, PHP)
Whilst they may raise some valid points, it's more important that you pick platforms you are familiar with. It's no point picking the latest platform but taking 6 months just to do a To-do app. Remember - frameworks and libraries are there to help you develop better and faster, not to hinder you with unnecessary complexity.
Pick something you understand, stick with it for a year, learn to be good at it, and if it still doesn't tick the right boxes for you, find something else. But it's better to be good at one 'outdated' platform and be productive than to be mediocre in three 'current' platforms and be lost 80% of the time.
And if anyone has the ignorance to say my X is better than your Y, just ask them 'Why?', and keep asking them 'Why?'. Chances are they don't know either.