Ember.js, Another year of churn, instability and festering frustrations.

I’ve been using Ember.js for years. Practically since it’s inception. That doesn’t make me smarter or more qualified, it just gives me a little more perspective [I like to think]. My current role is “lead Ember.js engineer” on a ten person product team. That is to say, it’s my job to keep up with changes to Ember.js, helper ensure good practices, file bugs, etc. I’ve also published and maintained a few add-ons. I’ve written this post in part to vent about growing frustrations and in part to see if other developers share some of the same concerns.

For a very long time the phrase, “stability without stagnation”, has been uttered by many on the Ember.js core team. It’s really just a cute way of saying, “things are changing, keep up or get left behind”. The churn of Ember.js has become exhausting. More and more I’m fielding questions from other team members about, “Why did this change?”, “How should I do it now?”, “This is different, but how is it any better?” and my personal favorite, “What’s the status of Ember-Data?”. I’ve become an Ember apologist just to mitigate the frustrations of my colleagues, some of whom who have compared Ember’s churn to that of Tapestry 3, 4 and 5.

So let’s talk about their frustrations, and mine.

We do our very best to “color inside the lines” as Tom Dale once put it. We’ve adopted ember-cli, we’ve adopted new APIs, we’ve discontinued the use of old APIs ASAP, and we frequently refactor to newer patterns (e.g. services, components). All of these have a cost to us. A cost to change the code, a cost to continue to educate team members and most importantly a risk of regressions for our users. After each “major” upgrade/refactor/whatever_you_call_it we review the high level net out. All to often the net out is, “We’re up to date on Ember. Things didn’t get easier, they didn’t get harder, they’ve just changed.”.

Let’s get specific about Ember 1.10.x — Ember 2.x.

Recently, we’ve spent a good bit of time cleaning up all of the deprecation warning and trying to practice Ember 2.x patterns. The first and probably most prominent example that comes to mind is {{bind-attr}}. I spent nearly a week of my life changing: `{{bind-attr class=”isActiveUser:enabled:disabled”}}` to `class=”{{if isActiveUser ‘enabled’ ‘disabled’}}”` and the high level net out of this change is as a previously stated, not better or worse, just different. The same can be said for computed property, `{{each}}` block helpers, `this.attrs`, “router resources”, angle-brackets”, the list goes on. It’s not really better, it’s just different.

Those were the easier parts of the refactor. They were tedious, but procedural. It’s a find, replace and test kind of workflow. The real challenge is all of the implicit lifecycle changes brought on by Glimmer and it’s attr replacement lifecycle. If your app at all uses jQuery plugins, or manually touches the DOM in any way, you’re in for a real treat. And after it’s all said and done, I’ve found Glimmer to be just a tad slower when rendering pages in our app.

Ember 2.x patterns — Quite another story. I did find some benefits to new patterns offered by Ember 2.x, but at the moment it’s very tough to utilize them. With 2.x `Ember.View` is being replaced with `Ember.Component`, but routable component’s haven’t landed, they’ve barely been touched. So out of the gate, you’re forced into continuing use of deprecated classes. The same can be said for query params and controllers. Not to mention the boilerplate that exists between the current routable views/controllers and building a component to replace them.

With Ember, proper code patterns have always been a bit hard to figure out. And if you try to swim upstream, you’ll get burned. The docs and guides cover the API really well, but they don’t cover holistic patterns. There is no definitive authority on how to structure large parts of your code in a way that is future proof, this recent effort was no exception.

A hackpad for brilliant engineers trying to solve tough problems.

Watching over the years at the feature priority has lead me to believe that many of the core team members want to solve technically tough problems, but have little interest in the lesser challenging ones. This isn’t a problem in it’s self, but it means that things like ember-data can get tossed to the side, despite being in high demand. FastBoot is great example. Months of effort, hundreds (likely thousands) of lines of code changed and dozens of regressions introduced for a feature that, as far as I can tell, no one really uses. Engines have constantly requested in one form or another to help larger and enterprise teams deal with the scale, despite constant promises in the RFC and at EmberConf, it’s MIA. Routable components are the last thing I’ll mention in this area. Since it’s inception, I’ve always thought of Ember’s router as it’s major differentiator, one of the very best things about Ember and the glue that holds your application together. Despite this, aside from the RFC, virtually no work has been done to bring it to life. Leaving many apps in a limbo state.

Communication.

I can’t even begin to tell you the number of times I’ve been caught off guard by a change that, “we [core team] have been wanting to make for a while”. I try very hard to keep up, it’s a large part of my job. I read every github issue, I follow discuss.emberjs.com, I frequent stackoverflow, I subscribe to the core meeting notes and I sit in the IRC/slack channels. Based solely on that, there shouldn’t be many changes that I don’t see coming, but it happens all too often. It’s hard to prepare for things coming down the pike when you have no warning.

Conclusions.

Sadly I don’t think things aren’t going to change. The future looks to be just as rocky for a while. Routable Components, angle-brackets, wide sweeping 2.x deprecations and code removal, container/registry refactoring, new ES6 adoptions, etc, etc, etc. The churn has burned out so many of us.

I sincerely hope that one or more of the core team members reads this and takes some of my frustrations to heart. It would be naive to believe these are the solely rantings of one developer [who admittedly is too spineless to give his name].