A Road to Ember 4.0

I've been building ambitious web applications with Ember since 2014. Overall I'm very satisfied with how productive I am, and how seamless the framework has improved without breaking old code. There are, however, some major areas that I think Ember can improve on if it wants to stay relevant and perhaps even win over some more converts as we advance from Ember 3.x to Ember 4.0.

Ember Core

Allow Native NPM Packages

I think a massively overlooked downside of Ember is that in order to import NPM packages, they either need to be specially wrapped as an Ember addon, which limits choice or imported using browserify, which is confusing to developers, especially newcomers to Ember. I think the goal of being able to just npm install or yarn install any package and having it "just work" should be high on the TODO list.

Replace Controllers and Templates with Routable Components

Ember has a lot of concepts that make it hard to learn - controllers and templates being two specifically that I think are hard to grasp, and due to routes and components, could be made unnecessary. This absolutely needs to be a priority when thinking of the future of Ember, which needs to be made simpler and easier to grasp, especially for developers of other frameworks that only really deal with components.

The saddest moment of my time as part of the Ember community was when Yehuda Katz closed the Routable Components RFC. At the end of his comment, he mentioned that some things should be worked on towards something resembling Routable Components, but there was no solid commitment or even a timetable. Overall it was a pretty big blow since this was such a needed feature that had also been promised and hyped up for a long time. I completely understand the core team's focus on gilmmer, which has been great and made all of our Ember apps faster. However, I think now is the time to get back to basics and simplify the core functionality of the framework by finally eliminating controllers and templates.

Choose One or Two Way Binding

The phrase "Data Down Actions Up" (DDAU) is said a lot in the Ember community - but two-way binding is still used extremely frequently. I can't really say that DDAU is really "The Ember Way" - in fact, I would say it is not. I think this is one of the biggest disconnects between what Ember says it does, and how people use it. I think it is important to bring what Ember says it does and how people use it into alignment but am ambivalent as to which path is best.

Ember Data

Support Non-Restful Actions

On every Ember app I've worked on eventually there are API calls that don't neatly fall into a RESTful action. From capturing and voiding charges, to sending a reminder email - these are all perfectly logical API calls but are not supported by Ember out of the box the way save or createRecord are. I've used the excellent ember-api-actions addon from Mike North that solves for this, but I think this should something the framework supports in a super easy way natively.

Eliminate Async Relationships

One of the best blog posts I've read in the past year was The case against async relationships in Ember Data by Ryan Toronto. In the post Ryan clarified that all of the confusion I've had around the ambiguous nature of the .get call to an ember data relationship property was due to it having multiple purposes.

Our main gripe with this API is that it combines the concerns of local data access with remote data fetching into a single method call. This makes it harder for developers to write expressive, intention-revealing code, especially because data loading is such a non-trivial part of developing Ember applications.

He's spot on, and EmberMap's Ember Data Storefront is a fairly well thought out vision for an async relationship free ember future.

Fully Embrace GraphQL as an Option

Ember predates GraphQL by a few years, so it's no surprise that it hasn't been officially supported yet.

However, it's impossible to ignore the meteoric rise that GraphQL has been on in the last year or so. Its benefits are immense yet in the Ember community, it is a niche addon at best, and a joke at worst.

Having used GraphQL myself, I've been blown away. Being able to declare exactly what data needs to be loaded leads to an extremely efficient query, with only one round trip to the server, a faster response time, and seamless navigation of deeply nested relationships. Even with the incredible JSONAPI::Resources gem on my Rails server, it's just not even close to how powerful GraphQL is.

I'm not alone in my love for GraphQL either, so many developers and companies are switching over to using it. Ember can't afford to ignore this game-changing technology any longer. Ember needs to include GraphQL as a first-class option for how Ember consumes API data - on par with JSONAPI. Furthermore, combining GraphQL with robust Ember Data models would actually be a superior developer experience than using GraphQL alone - which is something Ember can use to lure in new developers whose backends are GraphQL.

Add Native Websocket Support

I've been playing around with Elixir and Phoenix, which has awesome support for websockets. Building real-time web applications is tantalizing, and in many instances could fundamentally change how web applications are built. If Ember is to live up to its slogan of "A framework for ambitious web developers" then native Ember Data support for websockets is a must.

Ember Testing

Fix The Run Loop

I was lucky enough to attend last month's testing focused Ember NYC meetup with Robert Jackson. He said that one of his favorite recent additions to Javascript was async/await, which I wholeheartedly agree with! Unfortunately, I've had to regress to using callbacks many times because the Ember Run Loop breaks when testing code written with asnyc/await. He mentioned that this was something that needed to be fixed, and I would suggest it become a priority.

Improve The Fundamentals

Ember prides itself on being the best framework when it comes to testing, however, I think there is a lot of room here to be even better. Here are four things Ember could do:

  1. The testing page could really use a visual refresh.
  2. The testing page should be able to be usable while the app is testing, which is not the case now due to constant screen jitters.
  3. Eliminate the requirement to import services and components to get the tests to pass - this should just happen automatically.
  4. Have a better code organization than just naming tests with strings Unit | Component | component name - having the metadata about tests as real variables set in the test would allow for this.

Improve Error Handling

At times the error messages from Ember are cryptic and have a poor stack trace. Here are three ideas on how to make it better:

  1. Enable ember apps to optionally send test failure metadata to an as-yet-to-be-created central repository so that the Ember community can see aggregate statistics of what is failing. People can then upvote common failures or common confusing failures they don't know how to fix.
  2. Have a help button next to each failing test that will gather the needed data and start a thread on the ember discuss forum.
  3. Treat improving error messages and traceability as important features of new Ember releases and make a note of them in each release notes blog post.

Default to End-to-End Testing

Ember apps can't really be decoupled from the API that they consume. If the API changes, then the Ember app will break. However the way the Ember community has coalesced around "best practices" of testing is not to do true End-to-End tests, but instead to build out an entire mock API on each of their Ember apps using Mirage.

This is extremely time-consuming, a nightmare to maintain, hard to upgrade, easily falls out of sync with the real API, and at the end of the day doesn't actually test if the app works in the real world.

I think mocks have a time and a place, especially for third-party services, but they shouldn't be the center stage of "best practices" for how to test a single page app.

Instead, I think that true End-to-End testing, as laid out in this excellent blog post by Estelle DeBlois at DockYard should become the norm.

From the perspective of changing code in Ember to make this happen, I don't think there is really much to do. This is more of a mindset change within the Ember community of what constitutes good testing. To accomplish this, there would need to be guides, tutorials, blog posts, and real-life examples of companies that use Ember that do true End-to-End testing with a variety of backend technologies.

Keep an Eye towards the Future

I've been using Percy for over a year, and I'm very bullish on visual integration testing. I think a case could be made that it is a solid replacement for many tests that are currently manually written. At the very least, I'd love to see a tighter integration of visual integration tests into Ember as one of the core "best practices" methods that Ember apps are tested. There are some full-blown fancy solutions such as Cypress which does screenshots and video recordings so you can play back each step of a test, but even just tighter integration with Percy would be great.

Closing Thoughts

Overall I'm still a huge fan of Ember and use it in my job as well as my side projects. I think the community is top notch, and the philosophy of progress with stability is pretty spot on. There is a lot of work to be done to keep Ember relevant in a competitive landscape of view libraries and other frameworks. I've laid out some of my ideas, but the thing that gives me the most hope is the fact that I was asked by Ember to give my ideas in the first place. I'm really excited to read what other people in the community have to say and am hopeful that the core team will take some of our advice to heart when building the official 2018 Ember Roadmap. I'm hopeful that with time and forward progress Ember will bring in more developers, and continue to realize its vision of being "A framework for ambitious web developers" in an ever-changing world.