In this post, I'll go through what I think the JavaScript frameworks of the future should look like, and what I personally think they need to do (and do well) to succeed in the next 5 to 10 years in this fast-moving industry of ours.
In my opinion, JavaScript front-end frameworks should be as kids were back in the 1960's - seen and heard when they are called for and spend the rest of their young lives behaving impeccably, doing as they're told, so that they can grow up into well-adjusted applications without being a burden on society. No more, no less... It's a pipe dream right?!
We have framework fatigue
A short while ago, I gave Angular a bit of a hard time, and although there were mixed reactions, one thing that stood out for me when all the objections and agreements had settled, was that most developers don't know what they really want from a framework, other than it needs to be easy! Most just accept the status quo and bend to the will of the behemoth they are trying to tame, when in fact, it is them being tamed – all the while making compromises that should not need to be made.
Developers talk about the fatigue associated with having to keep up with the fact that a new JavaScript framework comes out every few weeks (some say every few days, but I think that's pushing it ;-)) and lament the fact that they don't have time to learn them all, and rightly so, why should we? This leaves many developers asking the question – which framework should I use? They ask their peers, they ask framework builders, they ask leaders in this space and they ask the internet in general. And do you think they ever get the same answer twice?
So some just throw their hands up and resign themselves to using what they've used before, or what they're told to use by others more senior (but no less disillusioned) on their team, or worse, what they're told to use by their boss who has almost no technical background.
There are also those that just want to drop frameworks altogether in favour of using the raw power of JavaScript, and I have felt like this many times myself before. There is merit in that approach, a chance to keep complete and utter control over your code base, and do away with the cruft that comes with 90% of any framework you choose, but the price you pay of course, is time to completion.
However, as the complexity grows, which is the case with any app that lives long enough or is useful enough, the inevitable conclusion is the same – you’ve either rolled yourself a nice big ball of mud there, or you've gone ahead and rolled your own framework.
Rails is a perfect example of where this was particularly well done, and as a result, people use it to build all sorts of applications that were never intended by the original design. Given its room for manoeuvre and flexibility, Rails has been able to weather the storm thrown at it from all angles. Of course, there are issues that crop up from time to time, but Rails has been largely successful over its lifetime so far.
The problem is we don't have a similar story in the JavaScript world. Well we have a few small ones, but none with comparable impact because the JavaScript community is infinitely larger now than Ruby ever was or will be. Moreover, because developers are approaching JavaScript from such a vast array of backgrounds, each doing it their way, you have a melting pot of diversity seldom experienced anywhere else.
So what does a JavaScript framework have to do in order to remain relevant in the coming years before we all decide we’ve had enough and just start using existing inferior tools or end up coding our own (inferior tools) from scratch? Here is my list…
Favour convention over configuration
Ten years ago and beyond, it was not uncommon to install a framework of choice and start by configuring the hell out of it. You were required to tell the framework everything it needed to know before you started building your actual app. I am not necessarily talking JavaScript here, but software frameworks in general.
Since then a number of frameworks, products, libraries and more, have adopted the notion of making assumptions about the commonalities most developers would choose. They build those in as defaults, and unless tinkered with, it will hit the ground running in default mode and probably just work. This convention-based model is a great time saver and can go a long way towards making sure the framework stays out of your way, which I’ll go through in more detail later.
But I still see way too many frameworks falling back to configuration where none should be required. Unfortunately, this is often due to poor architecture, and lack of foresight in being able to swap out pieces of the system, which I’ll delve into next.
Be modular so that I can change you
It’s a good thing being able to configure a framework, and even better when those configurations fall back on conventions, but being able to swap out parts of a framework, or better yet, leave them out entirely is crucial when it comes to building web apps today – especially with the explosion of mobile devices. Not everybody is on a blazing fast internet connection and can afford to download a ton of script required to prop up your framework.
Modularity for the sake of size is not the only reason though. The development cycle costs money, lots of it. In order to save money (especially in start-ups) it pays to keep the development cycle tight and efficient. Working with a modular framework allows development to be more easily compartmentalised, and allows new team members to grasp that part of the work more easily by being exposed to a shallower learning curve.
Another reason for a modular framework is when you like many things about it, but fundamentally disagree with certain parts for whatever reason. This has been known to happen – dependency injection, templates and binding just to name but a few – and can quite often turn what would have been a symbiotic relationship into a soul-sucking nightmare.
Plugins also obviously fall into this category. If the framework is modular, it stands to reason that many of its components would have been built as plugins themselves thereby fleshing out a model which other developers could adopt to expand the ecosystem, because the points of integration are already there. React components are an incredible example of how this idea can take off and really bring cohesion and momentum to the community as a whole.
Have strong opinions, but weakly held
What do I mean by that? Well, if you've heard about frameworks being opinionated, what that should translate to is that they favour convention over configuration as well as a good modularity story as I spoke about above.
But it’s more than that.
Opinions are exactly that – opinions – they are statements made by one party, but not necessarily agreed with by all. They are not doctrine. Doctrine cannot change, opinions can. They are malleable, and with enough persuasion or evidence, they will alter their point of view. That is what I mean by weakly held.
The framework builders will aim to guide you by supplying best practices and optimizations in such a way that you will fall into the pit of success if they can help it. The framework builders believe that this is the best, most efficient way to use their framework, but as is too often pointed out, the builders cannot possibly know all situations or environments their code is put to work. Sometimes their way is not the best way, and we need to be able to change that opinion.
If you happen to work in an environment that strictly controls the way that HTML mark-up is written and validated for example, then any syntax that a framework forces you to into, that violates XHTML standards, would need to be substituted for another syntax, otherwise you could not use the framework.
If the framework cannot accommodate that, then it is not opinionated, it is simply rigid, like an old man yelling at you to get off his lawn when you are clearly there to cut the grass. Not willing to give up its ways, the framework forces you to compromise on your standards (company or otherwise) and possibly even your overall quality.
If I want to use React to manage the binding and rendering on a particular grid of data in my app because of its size or complexity, and I need it to render fast, then swapping out at page level should be straightforward. I shouldn’t necessarily have to do it for the whole app, but rather choose the best solution for the situation that presents.
Situations like these crop up all the time when building apps. If we are using a rigid framework, we are required to apply countless workarounds and even hacks to appease the framework. We are not given the option of doing what we decide is best, and that is not strong opinion, weakly held – that is doctrine, which inevitably produces a great big ball of mud.
Stay out of my way
Conventions, modularity and strong opinions all sound like good selling points a framework should have, but this my friends is where the fine balancing act comes in. You see, the flip side of that coin also has a name. Can you guess what it is? That’s right; it’s called the learning curve. Naturally, the more conventions, points of integration and opinions a framework has, the steeper the learning curve imposed on the developer.
Now, I’m not a big fan of learning curves for the sake of learning curves, especially when it comes to on boarding my teams. If you are going to force developers into a specific way of doing things, either syntactically, or architecturally, you need to make sure it isn’t obtrusive and that the developer can elect to do it a different way should they choose to put in the work.
One can expect a certain amount of framework markers to pepper the code and mark-up in your app, but you would hope that they remain on the periphery as much as possible. It is not unheard of for teams to port entire apps from one framework to another; in fact, it is quite common. Any framework that makes this difficult to do is by definition, going to get in your way.
It is likely that you are writing more code to please the framework, than you are for building your app. Frameworks that do not do this are more likely easier to port away from, but by the same token, you probably wouldn’t end up doing that because it is not getting in the way of writing app code. So ironically, making it easier to port away actually ends up building more loyalty.
Aurelia is a relatively new framework, but built on top of mature ideas, and is a perfect example of this point. It is convention based, has incredible modularity and exercises many malleable opinions. This is especially true when it comes to their data binding system for example:
Two-way binding is bad I hear you say
No problem, force everything into one-way binding using built in conventions, knowing that you will need to handle some rendering or persistence manually.
I don’t like the way it binds at all, not the syntax, nothing!
No problem – rip it out and teach it your own binding or substitute it with one you’ve used before.
It’s not fast enough I need more speed!
No problem – if you think something like React can give you what you need there, then go head and tell it to use React instead.
When it comes down to it, I just want to write JavaScript and I want the framework to stay out of my way while I do that. I’m not interested in pleasing the framework; I’m interested in pleasing my boss and my customers. I want to build an app, and preferably using ES6 and beyond if I can help it, which brings me to my next point.
Embrace the future of JavaScript
Now this one is just ridiculous right? I mean, how can you possibly predict where the future is going, especially when it comes to JavaScript? OK, yes, we can all agree I don't mean crystal ball fluff here, but I think you already knew that.
I'm talking about all incredible things that some of the smartest folks in this field are coming up with here and now, with an eye on the future. I'm talking about ECMAScript 6 and 7 and onwards, all right all right, ES2015 if you insist.
We already know about the incredible work that transpiler teams such as Traceur and Babel are doing which allow us to clean up our code and write for the future, now, while deploying on yesterday’s landscape of browsers and devices. This was not impossible before transpilers, but incredibly prohibitive, as you had to tweak the hell out of your browsers (if they even supported the features). However, transpilers have brought the beauty of this to our developer teams here and now, with minimal fuss, and there’s no excuse not to use it going forward.
This is not just an interim step to get us over the hurdle of current browser ES5 support up to ES6 until things settle down. This will be an ongoing thing where JavaScript constantly improves, and transpilers allow us to take advantage of those new features in production, before they are even released. It’s crucial that the framework builders consider this and include it as part of their workflow.
If you’re going to throw annotations like CoffeeScript or TypeScript into the mix, then that’s all for the good, but for the love of all that is holy, please make it opt-in. Not everybody has drunk that particular Kool-Aid just yet, and you won’t be making any friends forcing it down people’s throats. I’m looking at you Angular 2.
Coupled with transpilers, I’m also talking about the testing, packaging and deployment solutions out there today which have enabled us to automate our lifecycle thoroughly. The Npm’s, Gulp’s and Grunt’s, Jasmine’s and Karma’s of the world must be embraced to complete the lifecycle.
In addition, don’t tie us to a specific back-end technology by making assumptions. Just as there are many front-end frameworks, so too, do we have a huge variety of back end providers – especially in this melting pot we’ve created. It could range anywhere from Node, to .Net, to Python, Ruby, PHP, Scala, Firebase, and even COBOL for crying out loud! Touting your framework as Isomorphic or whatever, when it is actually only applicable to a minute fraction of back-ends doesn’t help your cause, and can hardly be considered a feature. Be honest about what your framework is capable of, where it fits best if it has a particular niche, and help us as developers to make that decision of which framework to use for our purpose that much easier.
Conclusion
This is my shortlist of what I look for in the JavaScript framework of the future so that we can focus on what needs our attention most – our customer’s needs, with well tested, well architected code that is easy to write and more importantly, easy to understand.
If you think there are things I’ve missed out, or want to discuss some of the finer points, then by all means leave a comment or hit me up on Twitter. I’m always open to learning new things and new approaches. This is an exciting time to be working in the JavaScript arena, and I hope it’s only going to get better!
Images courtesy of gizmag.com, architecturelab.net and 2gbuildingservices