Q&A | RFC 176: JavaScript Modules API

Hi everyone!

With the release of 2.16, we will switch the default imports for blueprints to the format suggested by RFC 176.

The intention of this thread is to concentrate all your questions about it on a single place.


Hello guys,

Can you please explain the benefits from using this new import syntax from “vendor” package size point of view? As I understand we import only those functions that needed for current app. Do I need to change ember-cli-build.js file somehow?

Thank you.

There is a short answer, and a longer answer. I think the context behind the long answer is useful in understanding how the Ember project tries to develop features.

The short answer is that currently there are no bundle size benefits to using the new modules API. Check below for why that is. It is unlikely you will need to change ember-cli-build.js, what you will probably need to do is make sure some of your dependencies are up to date, like ember-cli-babel and babel-plugin-ember-modules-api-polyfill.

The end goal is to have the ember.js library be built by your application, like a regular addon. This will allow us to more easily do tree shaking (removing code that is not utilized), as well as what is called svelting (removing deprecated framework code).
By letting your app build ember.js, the build pipeline is also able to use the targets specified in your app’s configuration to avoid compiling to ES5 needlessly.

All of the above will eventually contribute to smaller builds. To get there we first need to move away from the Ember global, including the import Ember from 'ember'; namespacing, hence the new modules API like import Component from '@ember/component';.

However, refactoring ember.js’ internals is a big undertaking and blocking the new modules API on that refactor would mean the modules API would not land for many months, so we decided to take a progressive approach. What we are currently doing is actually using a babel plugin to transform your new modules API imports to the old import Ember from 'ember'; API. We are currently working on extracting the first actual package, which will be @ember/string.


Boot Options is definitely not intended to be a “reachable” thing – it is an “interface” that only exists to document the things you can pass in the “options bag” to boot. (That matches what the documentation says.)

In our app, we end up doing this everywhere:

import { inject as service } from '@ember/service';

There are two reasons for this:

  1. Sometimes we need to import inject from @ember/controller and @ember/service in the same file.
  2. In the usage site, we think service() is more appropriate and clear than inject(). It reads nicely next to { ..., foo: computed(...), bar: service(), ... } (“foo is a computed property, bar is a service”).

As of today, we have 52 instances of import { inject as service } ... in our app. I suspect we are not alone in the community.

Should we consider renaming this in Ember itself? Another solution is to make it a default export of a sub-path so it can be named by the importer as they wish.