The Future of Ember.js

There was a call for articles under the hashtag #emberjs2019 to discuss the future roadmap, priorities, and issues with Ember. I never did that in a timely fashion because I’m a bad person. So here it is anyway.

Matt Burgess

--

This is mostly in response to another article on Ember that was posted on Reddit. I wanted to respond to that in comments, but I thought my response served reasonably well as an article in its own right.

I actually don’t agree with this article at all. Or more particularly I agree with a lot of its concerns, but not its conclusions.

Ember Lost

Yep.

Ember Deserved To Lose

More debatable. And it’s also debatable why Ember lost and deserved to. I’m going to give my take in contrast to this one.

He is unquestionably right about the impact of React, and the follow-on effect that has on ecosystems, training, mindshare, etc. Momentum is definitely something React has that Ember doesn’t.

React beat Ember because React is simple and intuitive while Ember is complicated and confusing!

Here is where I start to disagree. Not because that’s not the perception, I totally agree that’s the perception. I disagree that it’s the reality. In fact, I think if there’s ever been one thing Ember has failed at it is this:

Ember continues to fail at messaging its benefits

I’ve heard people say “React is easy, Ember is hard” and knowledgable people say essentially “Yeah, but…” where they should be saying “No it’s not and here’s why”.

I’ve posted about this before in regard to React and Angular, specifically, rather than Ember, but it applies as well or more so.

React is easy to learn but only because it doesn’t do anything. It’s like saying .Net’s Razor templating engine is easy to learn… well yeah. But it’s never just React, is it? “React” might be easy to learn, but IMO React’s router is the single worst router of any current framework. It’s actually not React Router you want, it’s React Router Dom. It’s incredibly badly documented, with a changed API and as far as I can tell no official docs. Could be wrong there, but I literally learned out to use it from a now-superceded Medium article. Figuring out where to put it was the first part? App.js? index.js? SURE! Do I import the BrowserRouter component into the same file as the Routes? Where do I set up routes? The pattern used by React fairly common, that of providers wrapping components, is not (to me) an intuitive one. Having this is some weird shit to me.

<Provider store={store}>
<BrowserRouter>
<AppContainer />
</BrowserRouter>
</Provider>

Routes themselves are components, which are selectively switched on, which is… sort of odd, right? It’s the strangest way to store a finite state machine. Every other framework, including close-in-scope ones like Vue use an object to define routes.

const routes = [
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar }
];

Vue’s routing engine is really nice. Ember’s is also very nice, and relevant since we’re comparing them to React.

Router.map(function() {
this.route('foo');
this.route('bar');
});

Learning React is easy, but learning React Router is sort of a shit. I’ve done a buttload of React since, including some moderately complex SPAs and I know the router well. But it was knowledge that was hard-earned. Matching on exact routes still trips me up from time to time. Learning React’s router was an order of magnitude more difficult than learning any other framework’s router. Including Ember.

This is something Ember messages badly.

Then there’s Redux. Which you might need. Or you might not. Depending on your application’s bigness, which is itself a vague description that’s hard to determine up front.

Learning React might be easy, but learning Redux certainly wasn’t. I know a lot of people think redux is simple. I don’t get it. Maybe I’m stupider than the average bear. When I say “I don’t get it” I don’t mean I don’t get Redux. Actually I wrote a recent article on optimising Redux code to reduce boilerplate and improve visibility. But I don’t get why people say it’s simple. The process of implementing, accessing, and connecting to redux stores is anything but intuitive for a newcomer. It takes a lot of messing around to really “get”. Maybe just me.

The equivalent of all that in Ember is this.store by the way. Which is not just a state management tool but also a really powerful (and super cool) http request abstraction, so you don't need to set up a bunch of axios requests or whatever. This is an actual rich model layer.

Redux comes with loads of complexity. You’re not supposed to do http requests in it which makes it useless for real life so you have to add other things to it (like Thunk). But you find all of these things out as you go. They’re not up front. They’re not part of “React” so people dismiss them as complexities of doing stuff in React. But they’re booby traps waiting for you in Reactland. Footguns cocked and loaded. (Lol, cocked.)

With Ember there might be some stuff to learn, but you know that going in, there aren’t the surprises waiting.

This is something Ember messages badly.

There is complexity in Ember too. There is. Software that does hard things can be hard to learn. What I would challenge, though, is the presumption that if “stuff required to build a medium sized application” was laid all together in a pile, Ember would have a bigger pile, or a harder pile, or a pile with more… leaves in it. This isn’t a perfect metaphor.

In fact, I’d argue that by having everything learnable in one place, in one way, this is exactly where tools like Ember and Angular are actually easier to learn than React. This is also an advantage to Vue. Though it doesn’t have the large API surface area of Embular (for better or worse) at least core functionality like the router and state management are first-party. And vastly better for it.

This is something Ember messages badly.

But here’s where I start to disagree really wildly.

Ember is trapped in the outdated mindset of MVC in a world that has long moved on to Components.

I actually just fundamentally disagree. In my view, it’s the children who are wrong.

The world probably has moved onto components. But are they right to do so? Serious question. What is a component?

No no actually. What actually is a component? It’s a meaningless word. It’s the div of application architecture, a semantic-free, meaning-free, opinion-free box. So… what’s the appeal? Is that literally the point? If it does everything, does it actually do anything well?

Do we honestly think “the thing that controls how my application responds to a url” and “the thing that makes my checkbox” are and should be the same abstraction? Isn’t that… pardon my french, but isn’t that just fucking stupid? Am I missing something? I honestly don’t get this one.

I’ve heard people literally argue that one of the requirements they have for choosing a JavaScript framework is that it’s “component based”. When pressed they can provide no actual concrete benefit to this. Like, they can provide benefits to having components, but not only having components. But Vue is component-based, therefore that’s apparently a requirement.

This isn’t the case with all frameworks. We talk about “components” like they solve some sort of problem, but I’m not sure how. In React and Vue everything is a component, sure. But Ember, Angular and Aurelia make distinctions. I can’t quite remember Aurelia’s, it’s been a while, but IIRC essentially Aurelia makes a distinction by having a higher end abstraction, like an “element”. So if you wanted to make a tiny checkbox or a button it’s not the same larger abstraction as a component. Angular has a very very base abstraction called a module. Angular modules are places to group functionality and dependencies. This helps to keep root/base components clearer in larger applications.

Ember has a base abstraction, too, called a route. Ember’s architecture goal is to be URL-first. That “the URL is the primary driver of application state”. That abstraction is, imo, an entirely reasonable one. It’s one that conveys far more utility and clarity than a “component”. It has an actual use, meaning, intent. Components in Ember tend to be used for reusable UI elements, while routes do an excellent job of providing structure to the application’s “tree”.

This is something Ember messages badly.

Not only do I think the point made here is untrue, but I actually think the opposite is true.

Here’s a fun point. If you make an application in Ember without ever using a component you can have a way easier time. You get rid of all of the iffiness about how to nest components. You get rid of any need for controllers, you can put actions directly on the route.

Almost all of the complexity added in Ember goes away just using routes. Routes are fucking great and needing to add abstractions and complexity to support components is something that IMO Ember has chased waaaaaay too much.

Maybe it’s just me. It’s probably just me. I’m thinking aloud more than anything here. And maybe it’s a scale thing. I’m sure it is. But build a simple Ember app with just routes and see how nice and simple it is. Sure, yeah, it won’t scale. But maybe that would have been a better thing to chase than “how do we make it feel more like react”?

Trying to please two disparate groups

One of the issues I think Ember has always had is that it has a split requirement. How do you make a system that is suitable to both the extremely advanced, and the very new.

In my opinion it has focused entirely on the former, and not at all on the latter. It’s hard for Ember to grow when everyone who looks at it goes “there is too much here” and goes to Vue. And Ember has been very bad at selling its benefits.

And there are benefits. Over React, and over Vue. They’re not just benefits to advanced users, they’re benefits to new users. The benefits are primarily workflow and developer experience, something Ember messages badly. Ember’s CLI is exceptional. This is sold badly to React and Vue devs who will just dismiss that by saying Vue/React also has a CLI. Which is true but they greatly lack comparable functionality.

We talked above about the icky-ness of the react router, but not about the process of using it. Even taking into account whether the router is setup and configured.

React: Create a new file however you do that: Right click, create new file; touch components/About.js or whatever. Open whatever file has your routes in it. Import that new js file component and create a new Route component entry with the component and path. Open the component, decide whether it's a class or functional component, import React, add the relevant boilerplate (actually preferably do this first so Webpack doesn't shit) from your saved snippets or just type it in manually. Add a render function so it works properly, or make sure your function returns something renderable. An empty string perhaps.

Ember: Type ember g route about

This is a like-for-like comparison. Neither abstraction has any content. Neither abstraction has any behaviour. But both are completely navigable at this point, albeit to an empty page. The only real difference is that the Ember version already has acceptance tests.

Is Ember actually harder than React then? Really? Because things like this… don’t seem harder.

They seem much much easier.

This is something Ember messages badly.

It’s not just simple stuff like this either. Take a look at things like server side rendering. React has Next, which is great, but anything but simple. It’s not something you can just add to an existing React app as a feature. Essentially it’s a whole framework on top of the framework.

Ember, by comparison, has FastBoot, which actually is a first party solution. It is installed with ember install ember-cli-fastboot.

For the most part this will indeed render your existing application directly as a server rendered version of itself with zero setup and zero configuration. Fantastic workflow, and excellent developer experience.

But Ember is harder?

This is something Ember messages badly.

The same occurs when you look at other functionality. Setting up things like Sass used to be a nightmare in Create React App world, but thankfully they’ve improved it since. Still, it was always just ember install ember-cli-sass for me.

Elegant solutions exist for hard or annoying problems. Concurrency, auth, various ui toolkits (bootstrap, material design, tailwind, etc), animation. No importing, no configuration. Try doing route transition animations in React and in Ember and tell me which is hard.

Then there are other ones that solve VERY hard problems — Being able to go ember deploy staging is amazing. Takes some setup but it's super cool. Similarly Mirage, an exceptional backend mocking tool though it does require a bit of setup to get factories, etc working properly.

The ecosystem of quickly and easily integrated, community-approved add-ons with a curated system for finding and checking them is fantastic, and nothing like it exists in React. If you don’t agree, find a React date-picker that doesn’t suck.

This is something Ember messages badly.

To conclude here, in case you missed the subtle subtext, my feeling is that Ember messages a lot of things badly. It’s failing at the moment to sell its vision, its benefits. That leaves a lot of people to criticise Ember’s many failings whether valid (like its absurdly large bundle size) or less so (like it being “too hard” or “slow”) without any form of real counter. Too many criticisms are responded with “yeah but” rather than “is it though?” One advantage Ember has is that it’s excellent for complex and advanced applications and developers. But that doesn’t help with mindshare.

In my opinion what Ember needs the most is passionate and well informed advocacy at the early to intermediate level. People like me. This isn’t to make it about me. Rather this is to say that people like me are failing Ember too.

Back in 2.x I wrote an Ember e-book, and gave it out for free. But I have never updated it.

I’ve recorded videos of how to get a basic todo application up in under half an hour, including persistence, animation, and server side rendering. But I never put them online.

Ember is something I don’t do like I used to. It has been difficult to justify an Ember project vs a React project, especially in my workplace which has a React bias that imo isn’t fully justified by our actual requirements.

I’d like to steer some new projects towards Ember: specifically a large, complex, highly segmented, desktop-only, crud-based, long-lived enterprise backend system. On paper it’s a shoe-in for Ember. And yet somehow I am hesitant. There is a lot I’ll have to re-learn, and I can’t clearly see the innovation s-curve for returning Ember at this point. There probably is one, I just can’t see it.

If all goes well with that, further promotion and discussion of Ember when Octane really hits is something I’d like to do. I think Ember needs a lot more “How to Ember” and not so much “Dealing with async operations in testing deeply nested polymorphic components”.

Well, ideally more of both. And it needs to target new developers in neophyte-laden communities like Reddit, with examples, demonstrations, guides, and most of all, just… stuff. Ember projects need to be seen, to be shown. For every “look I made an Ember thing” there are a hundred react ones and a hundred and fifty Vue. This doesn’t necessarily make Vue better than Ember. But it makes it look like it. Ember’s visibility is relatively poor.

Ember has to find a way to turn that around. And to a large degree that’s up to people like me.

And yet.

I find myself a little unenthusiastic. Every time I start to get excited the wind gets taken out of my sails a bit. Ember Octane! New features! Modernising! Module unification! Svelte builds! Except… time is ticking on and Octane isn’t a thing. Yes, a lot of the features are available now, some feature flagged, some not, but for someone like me who wants a comprehensive feature set with well-established documentation, it’s just not enough.

To be honest, though, the killer for me was the module unification getting removed. Nothing for me highlights the disconnect between the experts and the newbies more than this. Because we can’t get it perfect we’re leaving it shit. Because without module unification you can’t do (as far as I understand) svelte build and tree shaking. Maybe I’m wrong there. I don’t know.

When I previously asked about timeline I was given an expectation of release for 3.11, a release which come and gone. Now it’s confirmed for 3.14, which puts it at a mid-October release. For a release promoted as “in 2018” and missing key (in my opinion crucial) features.

I’m finding it difficult to be passionate about Ember. I want to support it, because I genuinely think it has some of the best ideas for this kind of software development. I think its adherence to concepts of intelligent defaults, an integrated framework, developer experience, workflow, testing.

But too many roadmaps slipping, too many features falling out, benchmarks still dire especially on mobile. The new roadmap for 2019 talks about bundle size reductions as a major factor. If Octane is a guide it will be 2021 before significant impact is made on that. That’s too long away for me to even remotely consider.

--

--

Matt Burgess

Senior Web Developer based in Bangkok, Thailand. Javascript, Web and Blockchain Developer.