Ember CLI

Version 0.0.39

Although potentially exciting, this is still a work in progress project, use at your own risk.

Ember command line utility for ambitious web applications.

npm install -g ember-cli


Ember CLI is an Ember.js command line utility. It is based on the Ember App Kit project that was intended to be an ideal project template (structure) for Ember.js projects. It has proved to be very useful. It allowed users to quickly iterate while building real ambitious applications.

The goal for Ember CLI is to eventually replace Ember App Kit with a faster broccoli pipeline and strong conventions in place.

Assets Compilation

Ember CLI asset compilation is based on broccoli.

Broccoli has support for:

You can find a list of available plugins here.

All of this compilation happens in the background while you’re developing, rebuilding each time you change a file.


Ember CLI uses the ES6 Module Transpiler, which turns ES6 module syntax into AMD (RequireJS-style) modules. Using the transpiler, you can write code using tomorrow’s syntax, today.

In the past, building an Ember application with any sort of module system required lots of manual wiring-up of pieces. With the custom resolver included in Ember CLI, though, your modules are automatically used when needed. Your route in routes/post.js will know to use the controller in controllers/post.js and the template in templates/post.hbs. Of course, if your application does need to explicitly include a module, it’s only an import statement away.

Testing using CLI

All apps built with Ember CLI are preconfigured to use QUnit, the Ember Testing package, and the Ember QUnit. These tools, along with the same module system as your application, make both unit and integration tests a breeze to write.

Dependency Management

Ember CLI uses the Bower package manager, making it easy to keep your front-end dependencies up to date. NPM is used to manage internal dependencies but you can also use it to introduce your own.


Ember CLI is still very much WIP. It’s an ongoing community effort. We welcome your issues and PRs for features, bug fixes, and anything that would improve your quality of life as an Ember developer.

Talk to us here:


Currently, Ember CLI supports node 0.10.5 and npm 1.4.6.


The Ember App Kit project has proved to be quite useful. We have learned lots, and it allowed us to iterate quickly while building real ambitious applications.

While its initial incarnation is useful, it has several meta problems:

  1. It is not “simple” and appears daunting
  2. Because of inline configuration, the API surface area is massive
  3. 2 does not allow users to express the “what”, just the “how”. This prevents EAK from doing more of the heavy lifting itself
  4. 2 and 3 makes it quite tedious to upgrade

Rationale for #3

If we want to upgrade or swap in a faster build pipeline it would be a major pain currently. But with #3, in theory, it should be minimal pain.

Getting Started



First, install the latest stable version of Node (version 0.10.x).

To do so, either follow the installation instructions on nodejs.org, or use your preferred package manager (such as Homebrew on OS X) if you have one.

After installing Node, verify that Node is set up correctly by typing the following commands on the command line. Both should output help messages:

node --help
npm --help

Ember CLI

Once you’ve installed Node, you’ll need to install the Ember CLI globally with:

npm install -g ember-cli

This will give you access to the ember command-line runner.


You’ll need to install Bower, a package manager that keeps your front-end dependencies (including JQuery, Ember, and QUnit) up to date. This is as easy as running:

npm install -g bower

This will give you access to the bower command-line runner.


By default, your integration tests will run on PhantomJS. You can install via npm:

npm install -g phantomjs

Create a new project

Run the generator for your project:

ember new my-new-app

This will create a new my-new-app folder and generate an application structure for you.

Once the generation process finishes, launch the app:

cd my-new-app
ember server

navigate to http://localhost:4200 to see your new app in action.

navigate to http://localhost:4200/tests to see your test results in action.

Cloning an existing project

Alternatively, if you are checking out an existing Ember project created with ember-cli, you will need to install dependencies yourself before running the server:

git clone git@github.com:me/my-app.git
cd my-app && npm install && bower install
ember server

Upgrading an Ember CLI App

Use NPM to update to the latest released version of Ember CLI.

npm install --save-dev ember-cli

When you update to the latest version you may need to re-install files from the app blueprint and update Node NPM dependencies.

ember init

This will re-copy files from the project blueprint. You can choose to overwrite existing files or not. It will subsequently call npm install to update any changed dependencies.

Using Ember CLI


Prints out a list of available commands.

ember new <app-name>

Creates a folder called <app-name> and generates an application structure for you.

ember init

Generates an application structure for you in the current folder.

ember build

Builds the application depending on the environment.

ember server

Starts up the server. Default port is 4200.

ember generate <generator-name> <options>

Runs a specific generator. To see available generators, run ember help generate.

ember test

Run tests with Testem on CI mode. You can pass any options to Testem through testem.json, by default we’ll search for it under your project’s root or you can specify config-file.

Folder Layout


Contains your Ember application’s code. Javascript files in this folder are compiled through the ES6 module transpiler and concatenated into a file called app.js. See the table below for more details.


Contains the distributable (that is, optimized and self-contained) output of your application. Deploy this to your server!


This folder will be copied verbatim into the root of your built application. Use this for assets that don’t have a build step, such as images or fonts.


Includes unit and integration tests for your app, as well as various helpers to load and run your tests.


Various temporary output of build steps, as well as the debug output of your application (tmp/public).


Your dependencies, both those included with Ember CLI and those installed with Bower.


JSHint configuration.


Git configuration for ignored files.


Contains build specification for Broccoli.


Bower configuration and dependency list. See Managing Dependencies.


NPM configuration. Mainly used to list the dependencies needed for asset compilation.

Layout within app folder


Your application’s entry point. This is the module that is first executed.


The only actual page of your single-page app! Includes dependencies and kickstarts your Ember application.


Your route configuration. The routes defined here correspond to routes in app/routes/.


Contains your stylesheets, whether SASS, LESS, Stylus, Compass, or plain CSS (though only one type is allowed, see Asset Compilation). These are all compiled into app.css.


Your Handlebars templates. These are compiled to templates.js. The templates are named the same as their filename, minus the extension (i.e. templates/foo/bar.hbs -> foo/bar).

app/controllers/, app/models/, etc.

Modules resolved by the Ember CLI resolver. See Using Modules & the Resolver.


Add-ons are registered in NPM with a keyword of ember-addon. See a full list of existing add-ons registered in NPM here.

Using Modules & the Resolver

Rather than use AMD (Require.js) or CommonJS (Browserify) modules, apps built using Ember CLI use ES6 modules through the ES6 module transpiler. This means that you can build your apps using syntax from future JavaScript versions, but output AMD modules that can be used by existing JavaScript libraries today.

If you’ve built Ember.js apps before, you’re probably used to stuffing everything into a global namespace, following naming conventions so the app can automatically resolve its dependencies: App.FooRoute would know to render App.FooView by default. Using the custom resolver, Ember CLI applications have similar abilities, but using ES6 modules instead of a global namespace.

For example, this route definition in app/routes/index.js:

1 import Ember from "ember";
3 var IndexRoute = Ember.Route.extend({
4   model: function() {
5     return ['red', 'yellow', 'blue'];
6   }
7 });
9 export default IndexRoute;

Would result in a module called routes/index. Using the resolver, when Ember looks up the index route, it will find this module and use the object that it exports.

You can also export directly, i.e., without having to declare a variable:

1 import Ember from "ember";
3 export default Ember.Route.extend({
4   model: function() {
5     return ['red', 'yellow', 'blue'];
6   }
7 });

Of course, while automatic resolving is awesome, you can always manually require dependencies with the following syntax:

1 import FooMixin from "./mixins/foo";

Which will load the default export (aliased as FooMixin) from ./mixins/foo.js.

If you like you can also use an absolute path to reference a module. But keep in mind that using relative paths is considered best practice for accessing modules within the same package. To reference a module using an absolute path begin the path with the name defined in package.json:

1 import FooMixin from "appname/mixins/foo";

Note, that the name of the variable used in the exported module doesn’t have any influence on the resolver. It’s the filename that is used to resolve modules. Similarly, you can give any name to the variable into which you import a module when doing so manually; see how the module mixins/foo is assigned to variable FooMixin in the example above.

To use Ember or DS (for Ember Data) in your modules you must import them:

1 import Ember from "ember";
2 import DS from "ember-data";

Cyclic dependencies – are not yet supported at the moment, we are depending on: https://github.com/square/es6-module-transpiler/pull/126

Module Directory Naming Structure


Adapters with the convention adapter-name.js.


Components with the convention component-name.js. Remember, components are dasherized.


Controllers with the convention controller-name.js. Child controllers are defined in sub-directories, parent/child.js.


Helpers with the convention helper-name.js. Remember that you must register your helpers by exporting makeBoundHelper or calling registerBoundHelper explicitly.


Initializers with the convention initializer-name.js. Initializers are loaded automatically.


Mixins with the convention mixin-name.js.


Models with the convention model-name.js.


Routes with the convention route-name.js. Child routes are defined in sub-directories, parent/child.js. To provide a custom implementation for generated routes (equivalent to App.Route when using globals), use app/routes/basic.js.


Serializers for your models or adapter, where model-name.js or adapter-name.js.


Transforms for custom Ember Data attributes, where attribute-name.js is the new attribute.


Utility modules with the convention utility-name.js.


Views with the convention view-name.js. Sub-directories can be used for organization.

All modules in the app folder can be loaded by the resolver but typically classes such as mixins and utils should be loaded manually with an import statement. For more information, see Naming Conventions.

Resolving from template helpers

Ember has several template helpers that are used to easily resolve and render views and their contexts within a template. The resolver works with these helpers, too:

{{partial "foo"}} will render the template within templates/foo.hbs

{{view "foo"}} will render the view within views/foo.js

{{render "foo" <context>}} will render the view within views/foo.js using the controller within controllers/foo.js and the template templates/foo.hbs

Resolving Handlebars helpers

Ember automatically loads files under app/helpers if they contain a dash:

1 // app/helpers/upper-case.js
2 import Ember from "ember";
4 export default Ember.Handlebars.makeBoundHelper(function(value, options) {
5   return value.toUpperCase();
6 });

Handlebars helpers will only be found automatically by the resolver if their name contains a dash (reverse-word, translate-text, etc.) This is the result of a choice that was made in Ember, to help both disambiguate properties from helpers, and to mitigate the performance hit of helper resolution for all bindings. The other option is to define only the function used by the helper and then load it explicitly, like so:

In app/helpers/example.js:

1 export default function(value, options) {
2   return value.toUpperCase();
3 };

In app.js:

1 import Ember from "ember";
2 import exampleHelper from './helpers/example';
4 Ember.Handlebars.registerBoundHelper('example', exampleHelper);

In some-template.hbs:

{{example "foo"}}

In this example, because the helper is loaded explicitly, it’s the first argument to registerBoundHelper which makes the Handlebars renderer find it. The file name (example.js) and the name of the variable it’s been imported into (exampleHelper) could have been anything.

A common pattern with helpers is to define a helper to use your views (e.g. for a custom text field view, MyTextField a helper my-text-field to use it). It is advised to leverage Components instead. More concretely, instead of:

 1 // app/views/my-text-field.js
 2 import Ember from "ember";
 3 export default Ember.TextField.extend(
 4   // some custom behaviour
 5 });
 7 // app/helpers/my-text-field.js... the below does not work!!!
 8 import Ember from "ember";
 9 import MyTextField from 'my-app/views/my-text-field';
11 Ember.Handlebars.helper('my-text-field', MyTextField);

Do this:

1 // Given... app/components/my-text-field.js
2 import Ember from "ember";
4 export default Ember.TextField.extend({
5   // some custom behaviour...
6 });

Using global variables or external scripts

If you want to use external libraries that write to a global namespace (e.g. moment.js), you need to add those to the predef section of your project’s .jshintrc file and set its value to true. If you use the lib in tests, need to add it to your tests/.jshintrc file, too.

Module import validation

To prevent errors in import statements from reaching production, this project uses grunt-es6-import-validate. This task parses each module files export and import statements and verifies that what is being imported is actually exported by the referenced module.

If you are referencing a vendor module that is defined outside of the app folder you may have to add it to the whitelist in tasks/options/validate-imports.js.

Naming Conventions

When using Ember CLI its important to keep in mind that the Resolver changes some of the naming conventions you would typically use out of the box with Ember, Ember Data and Handlebars. In this section we review some of these naming conventions.

Module Examples

1 // app/adapters/application.js
2 import Ember from "ember";
3 import DS from "ember-data";
5 export default DS.RESTAdapter.extend({});
1 // app/components/time-input.js
2 import Ember from "ember";
4 export default Ember.TextField.extend({});
1 // app/controllers/stop-watch.js
2 import Ember from "ember";
4 export default Ember.ObjectController.extend({});

And if it’s a nested controller, we can declare nested/child controllers like such: app/controllers/posts/index.js.

1 // app/helpers/format-time.js
2 import Ember from "ember";
4 export default Ember.Handlebars.makeBoundHelper(function(){});
1 // app/initializers/observation.js
2 export default {
3   name: 'observation',
4   initialize: function() {
5     // code
6   }
7 };

Note: initializers are loaded automatically.

1 // app/mixins/evented.js
2 import Ember from "ember";
4 export default Ember.Mixin.create({});
1 // app/models/observation.js
2 import DS from "ember-data";
4 export default DS.Model.extend({});
1 // app/routes/timer.js
2 import Ember from "ember";
4 export default Ember.Route.extend({});

Nested routes as such: app/routes/timer/index.js or app/routes/timer/record.js.

1 // app/serializers/observation.js
2 import DS from "ember-data";
4 export default DS.RESTSerializer.extend({});
1 // app/transforms/time.js
2 import DS from "ember-data";
4 export default DS.Transform.extend({});
1 // app/utils/my-ajax.js
2 export default function myAjax() {};
<!-- app/index.hbs -->
{{view 'stop-watch'}}
1 // app/views/stop-watch.js
2 import Ember from "ember";
4 export default Ember.View.extend({});

And views, which can be referenced in sub-directories, but have no inheritance.

<!-- app/index.hbs -->
{{view 'inputs/time-input'}}
1 // app/views/inputs/time-input.js
2 import Ember from "ember";
4 export default Ember.TextField.extend({});


It is important to keep in mind that the Resolver uses filenames to create the associations correctly. This helps you by not having to namespace everything yourself. But there a couple of things you should know.

  • Dashes
    • file names
    • folder names
    • html tags/ember components
    • CSS classes
    • URLs
  • camelCase
    • JavaScript
    • JSON
All filenames should be lowercased
1 // models/user.js
2 import Ember from "ember";
3 export default Ember.Model.extend();
// controllers/sign-up.js
import Ember from "ember";
export default Ember.Controller.extend();
Nested directories

If you prefer to nest your files to better manage your application, you can easily do so.

1 // controllers/posts/new.js results in a controller named "controllers.posts/new"
2 import Ember from "ember";
3 export default Ember.Controller.extend();

You cannot use paths containing slashes in your templates because Handlebars will translate them back to dots. Simply create an alias like this:

1 // controllers/posts.js
2 import Ember from "ember";
3 export default Ember.Controller.extend({
4   needs: ['posts/details'],
5   postsDetails: Ember.computed.alias('controllers.posts/details')
6 });
<!-- templates/posts.hbs -->
<!-- because {{controllers.posts/details.count}} does not work -->

Views and Templates

Let’s say we were using Ember out of the box with the following view:

import Ember from "ember";
App.UserView = Ember.View.extend({});

We could easily embed this view into a container/parent using the Handlebars view helper:

{{view App.UserView}}

This is great. However, Ember CLI customizes the default Ember Resolver to help alleviate the issue of namespacing your objects (views, controllers, models, etc.) manually. The above example, as such, will not work in an Ember CLI project.

In Ember CLI our view would be declared like so:

1 // app/views/user.js
2 import Ember from "ember";
3 export default Ember.View.extend({});

We can then embed our view using the following convention:

{{view "user"}}

Note, that we did not namespace UserView. The resolver takes care of this for you. For more information about the default Ember resolver, check out the source here.


Test filenames should be suffixed with -test.js in order to run.

Using With Ember Data

The current beta Ember Data is included with Ember CLI.

Ember Data has recently undergone a major reboot, drastically simplifying it and making it easier to use with the Ember resolver. Here’s some tips for using it within Ember CLI.

To use ember-cli without Ember Data remove the dependency from package.json (the same applies for ic-ajax)

npm rm ember-cli-ember-data --save-dev


Models are critical in any dynamic web application. Ember Data makes making models extremely easy.

For example, we can create a todo model like so:

 1 // models/todo.js
 2 import DS from "ember-data";
 4 export default DS.Model.extend({
 5   title: DS.attr('string'),
 6   isCompleted: DS.attr('boolean'),
 7   quickNotes: DS.hasMany('quick-note')
 8 });
10 // models/quick-note.js
11 import DS from "ember-data";
13 export default DS.Model.extend({
14   name: DS.attr('string'),
15   todo: DS.belongsTo('todo')
16 });

Note, that filenames should be all lowercase and dasherized - this is used by the Resolver automatically.

Adapters & Serializers

Ember Data makes heavy use of per-type adapters and serializers. These objects can be resolved like any other.

Adapters can be placed at /app/adapters/type.js:

1 // adapters/post.js
2 import DS from "ember-data";
4 export default DS.RESTAdapter.extend({});

And its serializer can be placed in /app/serializers/type.js:

1 // serializers/post.js
2 import DS from "ember-data";
4 export default DS.RESTSerializer.extend({});

Application-level (default) adapters and serializers should be named adapters/application.js and serializers/application.js, respectively.


Writing a Test

  • ember-testing
  • helpers
  • unit/acceptance

The default tests in Ember CLI use the QUnit library. The included tests demonstrate how to write both unit tests and acceptance/integration tests using the new ember-testing package.

Test filenames should be suffixed with -test.js in order to run.

If you are using Pods to organize your application, be sure to add your podModulePrefix to the test resolver namespace.

To run the tests in your browser using the QUnit interface, run ember server and navigate to http://localhost:4200/tests. Note that just like your app, your tests will auto rebuild when ember server is running.

By default, your integration tests will run on PhantomJS. You can install via npm:

npm install -g phantomjs

CI Mode with Testem.

ember test will run your tests with Testem on CI mode. You can pass any option to Testem using a configuration file.

We plan to make your test runner pluggable, so you can use your favorite runner.

Using ember-qunit for integration tests

All Ember Apps come with built-in ember test helpers, which are useful for writing integration tests. In order to use them, you will need to import tests/helpers/start-app.js, which injects the required helpers.

Be sure to use the injected module function to invoke setup and teardown.

 1 import Ember from "ember";
 2 import { test } from 'ember-qunit';
 3 import startApp from '../helpers/start-app';
 4 var App;
 5 module('An Integration test', {
 6     setup: function() {
 7         App = startApp();
 8     },
 9     teardown: function() {
10         Ember.run(App, App.destroy);
11     },
12 });
13 test("Page contents", function() {
14     expect(2);
15     visit('/foos').then(function() {
16         equal(find('.foos-list').length, 1, "Page contains list of models");
17         equal(find('.foos-list .foo-item').length, 5, "List contains expected number of models");
18     });
19 });

Using ember-qunit for unit tests

An Ember CLI-generated project comes pre-loaded with ember-qunit which includes several helpers to make your unit-testing life easier, i.e.:

  • moduleFor
  • moduleForModel
  • moduleForComponent
moduleFor(fullName, description, callbacks, delegate)

The generic resolver that will load what you specify. The usage closely follows QUnit’s own module function. Its use can be seen within the supplied index-test.js:

 1 import { test, moduleFor } from 'ember-qunit';
 3 moduleFor('route:index', "Unit - IndexRoute", {
 4   // only neccessary if you want to load other items into the runtime
 5   // needs: ['controller:index']
 6   setup: function () {},
 7   teardown: function () {}
 8 });
10 test("it exists", function(){
11   ok(this.subject());
12 });


The resolver friendly name of the object you are testing.


The description that will group all subsequent tests under. Defaults to the fullname.


You are able to supply custom setup, teardown, & subject functionality by passing them into the callbacks parameter. If other objects should be loaded into Ember.js, specify the objects through the needs property.


To manually modify the container & the testing context, supply a function as the delegate matching this signature delegate(container, testing_context).

this.subject() calls the factory for the object specified by the fullname and will return an instance of the object.

moduleForModel(name, description, callbacks)

Extends the generic moduleFor with custom loading for testing models:

 1 import DS from "ember-data";
 2 import { test, moduleForModel } from 'ember-qunit';
 4 moduleForModel('post', 'Post Model', {
 5   needs: ['model:comment']
 6 });
 8 test('Post is a valid ember-data Model', function () {
 9   var post = this.subject({title: 'A title for a post', user: 'bob'});
10   ok(post);
11   ok(post instanceof DS.Model);
12 });


The name of the model you are testing. It is necessary to only supply the name, not the resolver path to the object(model:post => post).


The description that will group all subsequent tests under. Defaults to the name.


You are able to supply custom setup, teardown, & subject functionality by passing them into the callbacks parameter. If other objects should be loaded into Ember.js, specify the objects through the needs property.

Note: If the model you are testing has relationships to any other model, those must be specified through the needs property.

this.store() retrieves the DS.Store.

this.subject() calls the factory for the DS.Model specified by the fullname and will return an instance of the object.

moduleForComponent(name, description, callbacks)

Extends the generic moduleFor with custom loading for testing components:

 1 import Ember from "ember";
 2 import { test, moduleForComponent } from 'ember-qunit';
 4 moduleForComponent('pretty-color');
 6 test('changing colors', function(){
 7   var component = this.subject();
 9   Ember.run(function(){
10     component.set('name','red');
11   });
13   // first call to $() renders the component.
14   equal(this.$().attr('style'), 'color: red;');
16   Ember.run(function(){
17     component.set('name', 'green');
18   });
20   equal(this.$().attr('style'), 'color: green;');
21 });


The name of the component you are testing. It is necessary to only supply the name, not the resolver path to the object(component:pretty-color => pretty-color).


The description that will group all subsequent tests under. Defaults to the name.


You are able to supply custom setup, teardown, & subject functionality by passing them into the callbacks parameter. If other objects should be loaded into Ember.js, specify the objects through the needs property.

this.subject() calls the factory for the Ember.Component specified by the fullname and will return an instance of the object.

The first call this.$() will render out the component. So if you want to test styling, you must access the component via jQuery.

Writing your own test helpers

Ember testing provides that ability to register your own test helpers. In order to use these with ember-cli they must be registered before startApp is defined.

Depending on your approach, you may want to define one helper per file or a group of helpers in one file.

Single helper per file

1 // helpers/routes-to.js
2 export default Ember.Test.registerAsyncHelper('routesTo', function (app, url, route_name) {
3   visit(url);
4   andThen(function () {
5     equal(currentRouteName(), route_name, 'Expected ' + route_name + ', got: ' + currentRouteName());
6   });
7 });

This can then be used in start-app.js, like this

1 // helpers/start-app.js
2 import routesTo from './routes-to';
4 export default function startApp(attrs) {
5 //...

Group of helpers in one file

An alternative approach is to create a bunch of helpers wrapped in a self calling function, like this

 1 // helpers/custom-helpers.js
 2 var customHelpers = function() {
 3   Ember.Test.registerHelper('myGreatHelper', function (app) {
 4     //do awesome test stuff
 5   });
 7   Ember.Test.registerAsyncHelper('myGreatAsyncHelper', function (app) {
 8     //do awesome test stuff
 9   });
10 }();
12 export default customHelpers;

which can be used in start-app.js

1 // helpers/start-app.js
2 import customHelpers from './custom-helpers';
4 export default function startApp(attrs) {
5 //...

Once your helpers are defined, you’ll want to ensure that they are listing in the .jshintrc file within the test directory.

1 // /tests/.jshintrc
2 {
3   "predef": [
4     "document",
5     //...
6     "myGreatHelper",
7     "myGreatAsyncHelper"

Asset Compilation

Raw Assets

  • public/assets vs app/styles

For adding images, fonts, or other assets use the public/assets folder. For example you can do public/assets/images, and in your templates using /assets/images/logo.png or from stylesheets using url('/assets/images/background.jpg').


Ember CLI supports plain CSS out of the box. You can add your css styles to app/styles/app.css and it will be served at assets/application-name.css.

For example, to add bootstrap in your project you need to do the following:

bower install --save-dev bootstrap

In Brocfile.js add the following:


it’s going to tell Broccoli that we want this file to be concatenated with our vendor.css file.

To use a CSS preprocessor, you’ll need to install the appropriate Broccoli plugin. When using a preprocessor, Broccoli is configured to look for an app.less, app.scss, or app.styl manifest file in app/styles. This manifest should import any additional stylesheets.

The compiled css-files are minified by broccoli-clean-css or broccoli-csso, if it is installed locally. You can pass minifer-specific options to them using the minifyCSS:options object in your brocfile. Minification is enabled by default in the production-env and can be disabled using the minifyCSS:enabled switch.

All your preprocessed stylesheets will be compiled into one file and served at assets/app.css.


  • Relative pathing gets changed (how to customize?)
  • @import statements -> concat


To enable LESS, you’ll need to add broccoli-less-single to your NPM modules.

npm install --save-dev broccoli-less-single


To enable Sass (SCSS without Sass), you’ll need to add broccoli-sass to your NPM modules.

npm install --save-dev broccoli-sass


To enable Stylus, you must first add broccoli-stylus-single to your NPM modules:

npm install --save-dev broccoli-stylus-single


To enable CoffeeScript, you must first add ember-cli-coffeescript to your NPM modules:

npm install --save-dev ember-cli-coffeescript

The modified package.json should be checked into source control. CoffeeScript can be used in your app’s source and in tests, just use the .coffee extension on any file.

The ES6 module transpiler does not directly support CoffeeScript, but using them together is simple. Use the ` character to escape out to JavaScript from your .coffee files, and use the ES6 syntax there:

1 # app/models/post.coffee
2 `import Ember from 'ember'`
3 `import User from 'appkit/models/user'`
5 Post = Ember.Object.extend
6   init: (userId) ->
7     @set 'user', User.findById(userId)
9 `export default Post`

Note that earlier versions of the transpiler had explicit support for CoffeeScript, but that support has been removed.


To enable EmberScript, you must first add broccoli-ember-script to your NPM modules:

npm install --save-dev broccoli-ember-script

Note that the ES6 module transpiler is not directly supported with Emberscript, to allow use of ES6 modules use the ` character to escape raw Javascript similar to the CoffeeScript example above.


For Emblem, run the following commands:

npm install --save-dev broccoli-emblem-compiler

Fingerprinting and CDN URLs

Fingerprinting is done using the addon broccoli-asset-rev (which is included by default).

When environment is production (e.g. ember build --environment=production), the addon will automatically fingerprint your js, css, png, jpg, and gif assets by appending an md5 checksum to the end of their filename (e.g. assets/yourapp-9c2cbd818d09a4a742406c6cb8219b3b.js). In addition, your html, js, and css files will be re-written to include the new name. There are a few options you can pass in to EmberApp in your Brocfile.js to customize this behavior.

  • enabled - Default: app.env !== 'production' - Boolean. Enables fingerprinting if true, otherwise, fingerprinting is disabled. Noticed that by default it is true only if current environment is production.

  • exclude - Default: [] - An array of strings. If a filename contains any item in the exclude array, it will not be fingerprinted.
  • extensions - Default: ['js', 'css', 'png', 'jpg', 'gif'] - The file types to add md5 checksums.
  • prepend - Default: '' - A string to prepend to all of the assets. Useful for CDN urls like https://subdomain.cloudfront.net/
  • replaceExtensions - Default: ['html', 'css', 'js'] - The file types to replace source code with new checksum file names.

As an example, this Brocfile will exclude any file in the fonts/169929 directory as well as add a cloudfront domain to each fingerprinted asset.

 1 var app = new EmberApp({
 2   name: require('./package.json').name,
 4   minifyCSS: {
 5     enabled: true,
 6     options: {}
 7   },
 9   fingerprint: {
10     exclude: ['fonts/169929'],
11     prepend: 'https://sudomain.cloudfront.net/'
12   },
14   getEnvJSON: require('./config/environment')
15 });

The end result will turn

<script src="assets/appname.js">
background: url('/images/foo.png');


<script src="https://subdomain.cloudfront.net/assets/appname-342b0f87ea609e6d349c7925d86bd597.js">
background: url('https://subdomain.cloudfront.net/images/foo-735d6c098496507e26bb40ecc8c1394d.png');

You can disable fingerprinting in your Brocfile.js:

var app = new EmberApp({
  fingerprint: {
    enabled: false

Or remove the entry from your EmberApp and broccoli-asset-rev from your package.json.

Managing Dependencies

Ember CLI uses Bower for dependency management.

Bower Configuration

The Bower configuration file, bower.json, is located at the root of your Ember CLI project, and lists the dependencies for your project. Changes to your dependencies should be managed through this file, rather than manually installing packages individually.

Executing bower install will install all of the dependencies listed in bower.json in one step.

Ember CLI is configured to have git ignore your vendor directory by default. Using the Bower configuration file allows collaborators to fork your repo and get their dependencies installed locally by executing bower install themselves.

Ember CLI watches bower.json for changes. Thus it reloads your app if you install new dependencies via bower install --save <dependencies>.

Further documentation about Bower is available at their official documentation page.

Compiling Bower Assets

In your Brocfile.js specify a dependency before calling app.toTree(). The following example scenarios should illustrate how this works.

Javascript Assets

Standard Non-AMD Asset

Provide the asset path as the first and only argument:

1 app.import('vendor/momentjs/moment.js');
Standard AMD Asset

Provide the asset path as the first argument, and the list of modules and exports as the second:

 1 app.import('vendor/ic-ajax/dist/named-amd/main.js', {
 2   exports: {
 3     'ic-ajax': [
 4       'default',
 5       'defineFixture',
 6       'lookupFixture',
 7       'raw',
 8       'request',
 9     ]
10   }
11 });

To use this asset in your app, import it. For example, with ic-ajax, when to use ic.ajax.raw:

1 import { raw as icAjaxRaw } from 'ic-ajax';
2 //...
3 icAjaxRaw( /* ... */ );
Environment Specific Assets

If you need to use different assets in different environments, specify an object as the first parameter. That objects keys should be the environment name, and the values should be the asset to use in that environment.

1 app.import({
2   development: 'vendor/ember/ember.js',
3   production:  'vendor/ember/ember.prod.js'
4 });
Customizing a built-in Asset

This is somewhat non-standard, but suppose that you have different versions of Ember specified (using the canary builds for example). You would simply manipulate the vendor tree that is passed in to the EmberApp constructor:

 1 var EmberApp  = require('ember-cli/lib/broccoli/ember-app');
 2 var fileMover = require('broccoli-file-mover');
 4 var vendorTree = fileMover('vendor', {
 5   files: {
 6     'ember-dev/ember.js': 'ember/ember.js',
 7     'ember-prod/ember.prod.js': 'ember/ember.prod.js'
 8   }
 9 });
11 var app = new EmberApp({
12   name: require('./package.json').name,
13   trees: {
14     vendor: vendorTree
15   }
17   getEnvJSON: require('./config/environment')
18 });
Test Assets

You may have additional libraries that should only be included when running tests (such as qunit-bdd or sinon). These can be merged into your assets in your Brocfile.js:

 1 var EmberApp = require('ember-cli/lib/broccoli/ember-app');
 2 var pickFiles = require('broccoli-static-compiler');
 3 var mergeTrees = require('broccoli-merge-trees');
 5 var app = new EmberApp({
 6 // snip
 7 });
 9 var qunitBdd = pickFiles('vendor/qunit-bdd/lib', {
10     srcDir: '/',
11     files: ['qunit-bdd.js'],
12     destDir: '/assets'
13 });
15 module.exports = mergeTrees([app.toTree(), qunitBdd]);

Be sure to add the appropriate script tag for your test library.

<script src="assets/qunit.js"></script>
<script src="assets/qunit-bdd.js"></script>


Static CSS

Provide the asset path as the first argument:

1 app.import('vendor/foundation/css/foundation.css');

All style assets added this way will be concatenated and output as /assets/vendor.css.

Dynamic Styles (SCSS, LESS, etc)

The vendor trees that are provided upon instantiation are available to your dynamic style files. Take the following example (in app/styles/app.scss):

1 @import "vendor/foundation/scss/normalize.scss";

Other Assets

Using app.import()

All other assets like images or fonts can also be added via import(). By default, they will be copied to dist/ as they are.

1 app.import('vendor/font-awesome/fonts/fontawesome-webfont.ttf');

This example would create the font file in dist/font-awesome/fonts/fontawesome-webfont.ttf.

You can also optionally tell import() to place the file at a different path. The following example will copy the file to dist/assets/fontawesome-webfont.ttf.

1 app.import('vendor/font-awesome/fonts/fontawesome-webfont.ttf', {
2   destDir: 'assets'
3 });
Using broccoli-static-compiler

With the broccoli-static-compiler package, (parts of) a bower-installed package can be used as assets as-is. First ensure that the Broccoli packages needed to build are installed:

npm install --save-dev broccoli-static-compiler
npm install --save-dev broccoli-merge-trees

Add these imports to the top of Brocfile.js, just below the EmberApp require:

1 var mergeTrees = require('broccoli-merge-trees');
2 var pickFiles = require('broccoli-static-compiler');

At the bottom of Brocfile.js we merge assets from a bower dependency with the main app tree:

 1 // Remove this line:
 2 // module.exports = app.toTree()
 4 // Copy only the relevant files. For example the WOFF-files and stylesheets for a webfont:
 5 var extraAssets = pickFiles('vendor/a-lovely-webfont', {
 6    srcDir: '/',
 7    files: ['**/*.woff', '**/stylesheet.css'],
 8    destDir: '/assets/fonts'
 9 });
11 // Merge the app tree and our new font assets.
12 module.exports = mergeTrees([app.toTree(), extraAssets]);

In the above example the assets from the fictive bower dependency called a-lovely-webfont can now be found under /assets/fonts/, and might be linked to from index.html like so:

<link rel="stylesheet" href="assets/fonts/lovelyfont_bold/stylesheet.css">

Generators & Blueprints

Ember CLI ships with blueprints for many of the entities you’ll need in your app.

ember generate route foo

  create app/routes/foo.js
  create app/templates/foo.hbs
  create tests/unit/routes/foo-test.js

To see a list of all available blueprints, use ember help generate:

ember help generate

Requested ember-cli commands:

ember generate <blueprint> <options...>
  Generates new code from blueprints
  aliases: g
  --dry-run (Default: false)
  --verbose (Default: false)

  Available blueprints:

You can define your own blueprints using ember generate blueprint <name>:

ember generate blueprint foo

  create blueprints/.jshintrc
  create blueprints/foo/files/.gitkeep
  create blueprints/foo/index.js

Blueprints in your project’s directory take precedence over those packaged with ember-cli. This makes it easy to override the built-in blueprints just by generating one with the same name.

Blueprint Structure

A blueprint is a bundle of template files with optional install logic.

Blueprints follow a simple structure. Let’s take the built-in controller blueprint as an example:

├── files
│   ├── app
│   │   └── controllers
│   │       └── __name__.js
│   └── tests
│       └── unit
│           └── controllers
│               └── __name__-test.js
└── index.js


files contains templates for the all the files to be installed into the target directory.

The __name__ placeholder is subtituted with the dasherized entity name at install time. For example, when the user invokes ember generate controller foo then __name__ becomes foo.

Template Variables (AKA Locals)

Variables can be inserted into templates with <%= someVariableName %>.

For example, in the built-in util blueprint files/app/utils/__name__.js looks like this:

export default function <%= camelizedModuleName %>() {
  return true;

<%= camelizedModuleName %> is replaced with the real value at install time.

The following template variables provided by default:

  • dasherizedPackageName
  • classifiedPackageName
  • dasherizedModuleName
  • classifiedModuleName
  • camelizedModuleName

packageName is the project name as found in the project’s package.json.

moduleName is the name of the entity being generated.

The mechanism for providing custom template variables is described below.


index.js contains a subclass of Blueprint. Use this to customize installation behaviour.

var Blueprint = require('ember-cli/lib/models/blueprint');

module.exports = Blueprint.extend({
  locals: function(options) {
    // Return custom template variables here.
    return {};

  afterInstall: function(options) {
    // Perform extra work here.

As shown above, there are two hooks available: locals and afterInstall.


Use locals to add custom tempate variables. The method receives one argument: options. Options is an object containing general and entity-specific install options.

When the following is called on the command line:

ember generate controller foo type:array --dry-run

The object passed to locals looks like this:

  entity: {
    name: 'foo',
    options: {
      type: 'array'
  dryRun: true

This hook must return an object. It will be merged with the aforementioned default locals.


The afterInstall hook receives the same options as locals. Use it to perform any custom work after the files are installed. For example, the built-in route blueprint uses the afterInstall hook to add relevant route declarations to app/router.js.

Common Issues

npm package manangement with sudo

Installing packages such as bower with sudo powers can lead to permissions issues and ultimately to problems installing dependencies.

For example

Uncaught Error: Could not find module ember/resolver loader/loader.js:42

can be caused by installing bower with sudo. See #354 for details.

Installing from behind a proxy

If you’re behind a proxy, you might not be able to install because ember-cli — or some of its dependencies — tries to git clone a git:// url. (In this scenario, only http:// urls will work).

You’ll probably get an error like this:

npm ERR! git clone git://github.com/jgable/esprima.git Cloning into bare repository '/home/<username>/.npm/_git-remotes/git-github-com-jgable-esprima-git-d221af32'...
npm ERR! git clone git://github.com/jgable/esprima.git 
npm ERR! git clone git://github.com/jgable/esprima.git fatal: unable to connect to github.com:
npm ERR! git clone git://github.com/jgable/esprima.git github.com[0:]: errno=Connection timed out
npm ERR! Error: Command failed: fatal: unable to connect to github.com:
npm ERR! github.com[0:]: errno=Connection timed out

This is not a ember-cli issue per se, but here’s a workaround. You can configure git to make the translation:

bash git config --global url."https://".insteadOf git://

Usage with SublimeText 3

If you are using SublimeText 3 with ember-cli, by default it will try to index all files in your tmp directory for its GoToAnything functionality. This will cause your computer to come to a screeching halt @ 90%+ CPU usage. Simply remove these directories from the folders ST3 watches:

Sublime Text -> Preferences -> Settings -User

// folder_exclude_patterns and file_exclude_patterns control which files
// are listed in folders on the side bar. These can also be set on a per-
// project basis.
"folder_exclude_patterns": [".svn", ".git", ".hg", "CVS", "tmp/class-*", "tmp/es_*", "tmp/jshinter*", "tmp/replace_*", "tmp/static_compiler*", "tmp/template_compiler*", "tmp/tree_merger*", "tmp/coffee_script*", "tmp/concat-tmp*", "tmp/export_tree*", "tmp/sass_compiler*"]

Using canary build instead of release

In bower.json instead of a version number use:

"ember": "components/ember#canary",

And, following dependencies add resolutions:

"resolutions": {
  "ember": "canary"

This can also be applied to Ember Data:

"ember-data": "components/ember-data#canary",

And, adding to resolutions:

"resolutions": {
  "ember-data": "canary"

Wipe your vender directory clean then run bower install.

Removing default ember-cli libraries

  • To use ember-cli without Ember Data

npm rm ember-cli-ember-data --save-dev

  • To use ember-cli without ic-ajax

npm rm ember-cli-ic-ajax --save-dev


You can easily deploy your Ember CLI application to a number of places.



Change directories to your Ember CLI application’s. Now, create your new Heroku application with the Ember CLI buildpack…

heroku create <OPTIONAL_APP_NAME> --buildpack https://github.com/tonycoco/heroku-buildpack-ember-cli.git

You should be able to now deploy your Ember CLI application with Heroku’s git hooks…

git commit -am "Empty commit for Heroku deployment" --allow-empty
git push heroku master

Need to make a custom nginx configuration change? No problem. In your Ember CLI application, add a config/nginx.conf.erb file. You can copy the existing configuration file and make your changes to it.

History API and Base URL

If you are deploying the app to somewhere other than the root URL (/), you will need to configure the value of baseUrl in config/environment.js. For example

1 // config/environment.js
2   if (environment === 'production') {
3     ENV.baseURL = '/path/to/ember/app/';

This value is used to set the value of base in index.html, e.g. <base href="/path/to/ember/app/" />, as this is required for the History API, and thus also the Router, to function correctly.



  • [BUGFIX] ember build --watch should run until SIGTERM. #1197
  • [BUGFIX] Failed build should return non-zero exit code. #1169
  • [BUGFIX] improve startup time by up to 3x
  • [BUGFIX] Ensure ember generate always operate in relation to project root. #1165
  • [ENHANCEMENT] Upgrade ember-cli-ember-data to 0.1.0. #1178
  • [BUGFIX] Update ember-cli-ic-ajax to prevent warnings. #1180
  • [BUGFIX] Throw error when trailing slash present in argument to ember generate. #1184
  • [ENHANCEMENT] Don’t expect Ember or Em to be global in tests. Ember or Em needs to be imported. #1201
  • [BUGFIX] Make behaviour of --dry-run more obvious & add --skip-npm and --skip-bower. #1205
  • [ENHANCEMENT] Remove .gitkeep files from ember init inside an existing project #1209
  • [ENHANCEMENT] Addons can add commands to the local ember command. #1196
  • [ENHANCEMENT] Addons can implement a postBuild hook. #1215
  • [ENHANCEMENT] Addons can add post-processing steps to the Brocfile.js process. #1214
  • [ENHANCEMENT] broccoli-asset-rev has been moved to an addon using the standard addon post-processing hooks. #1214
  • [ENHANCEMENT] Allow app.toTree to accept an array of additional trees to merge in the final output. #1214
  • [BUGFIX] Only run JSHint after preprocessing. #1221
  • [ENHANCEMENT] Addons can add blueprints. #1222
  • [ENHANCEMENT] Allow testing of production assets. #1230
  • [ENHANCEMENT] Provide Ember CLI version to Project model. #1239
  • [BREAKING ENHANCEMENT] Split app/templates into its own tree to prevent preprocessing template files as if they were JavaScript. #1238
  • [ENHANCEMENT] Print a warning when using app.import for assets in the root of vendor/ (this is a significant performance penalty).
  • [ENHANCEMENT] Model generation no longer requires an attribute type. #1252
  • [ENHANCEMENT] Allow vendor files to be configurable. #1187


  • accidentally deploy with node v0.0.11 which builds an invalid package


  • [BUGFIX] ensure the CLI exits with the correct status, fixes hanging tests and some non-graceful exit cleanups #1150
  • [BUGFIX] Ensure EDITOR is set before allowing edit in ember init. #1090
  • [BUGFIX] Display message to user when diff cannot be applied cleanly #1091
  • [ENHANCEMENT] Notify when an ember-cli update is available, and add ember update command. #899
  • [BUGFIX] Ensure that build output directory is cleaned up properly. #1122
  • [BUGFIX] Ensure that non-zero exit code is used when running ember test with failing tests. #1123
  • [BREAKING ENHANCEMENT] Change the expected interface for the ./server/index.js file. It now receives the instantiated express server. #1097
  • [ENHANCEMENT] Allow addons to provide server side middlewares. #1097
  • [ENHANCEMENT] Automatically pluralize the attribute when generating a model. #1120
  • [BUGFIX] Make sure non-dasherized model attributes are also added to generated tests. #1120
  • [ENHANCEMENT] Upgrade ember-qunit-notifications to 0.0.3. #1117
  • [ENHANCEMENT] Allow addons to specify load ordering. #1132
  • [ENHANCEMENT] Adds ember build --watch #1131
  • [BREAKING ENHANCEMENT] Accept options as second parameter of ember-app#import. Pass modules as exports. #1121


  • deployed bundled package with outdated bundled depds… Likely user error (by @stefanpenner)


  • [BUGFIX] Ensure that vendored JS files are concatted in a safe way (to prevent issues with ASI). #988
  • [ENHANCEMENT] Use the Project model to load the project name and environment configuration (removes boilerplate from Brocfile.js). #989
  • [BUGFIX] Pass --port option through when calling ember test --port 8987 (allows overriding the port when running concurrent ember test commands). #991
  • [ENHANCEMENT] Add .ember-cli configuration file. #563
  • [ENHANCEMENT] Add edit capability to ember init. #1000
  • [ENHANCEMENT] Add the current environment to the application config (the MyApplicationENV global). #1017
  • [BUGFIX] Ensure that the project .jshintrc file is looked up in the project’s root. #1019
  • [ENHANCEMENT] Allow addons to hook into the application build process. #1025
  • [ENHANCEMENT] Allow addons to register custom preprocessors. #1030
  • [BUGFIX] Prevent route blueprint adding duplicate entries to router.js #1042
  • [ENHANCEMENT] Add blueprint listing in ember help generate. #952
  • [BUGFIX] Add missing descriptions for build, serve, and test commands. #1045
  • [ENHANCEMENT] Do not remove output directory. This allows easier cross-project symlinking (previous behavior broke the link when the output path was destroyed). #1034
  • [ENHANCEMENT] Keep output path (/dist by default) up to date with both ember server and ember build. #1034
  • [ENHANCEMENT] Use the ember-cli-ic-ajax addon to bring in ic-ajax. #1047
  • [ENHANCEMENT] Use the ember-cli-ember-data addon to bring in ember-data. #1047
  • [BUGFIX] Allow fingerprinting to be enabled/disabled in a more custom way. #1066
  • [ENHANCEMENT] Use ember-addon as the “addon” keyword. #1071
  • [ENHANCEMENT] loader should now support CJS mode of AMD.
  • [ENHANCEMENT] Upgrade broccoli-asset-rev to 0.0.6 and allow passing a customHash in fingerprint options. #1024


  • [BUGFIX] broccoli-es6-safe-recast now once again has one-at-a-time semantics for incremental rebuilds
  • [BUGFIX] upgrade broccoli-sane-watcher to include better error messages when attempting to watch non-existent files
  • [ENHANCEMENT] Allow opting out of ES3SafeFilter. #966
  • [ENHANCEMENT] Provide --watcher option for switching between polling and events-based file watching. #970
  • [BUGFIX] Ensure that tmp/ is cleaned up after running ember server or ember test --server. #971
  • [BUGFIX] Fix errors with certain generate commands that depend on inflection. f016820
  • [BUGFIX] Do not wrap vendor assets in eval when wrapInEval is set. #983
  • [ENHANCEMENT] Use wrapInEval by default for application assets when running in development. #983


  • [BUGFIX] broccoli-sane-watcher now recovers after filters throw #940
  • [ENHANCEMENT] Use ember-data.prod.js when ENV=production #909.
  • [BUGFIX] Ensure that config/environment is findable and required when setting up baseURL for server. #916
  • [BUGFIX] Fix importing of non-JS/CSS #915
  • [ENHANCEMENT] Use window.MyProjectNameENV instead of window.ENV. #922
  • [BUGFIX] Disallow projects with periods in their name. #927
  • [ENHANCEMENT] Allow customization of Javascript minification options. #928
  • [BUGFIX] TestServer now waits until the build is done before starting. #932
  • [ENHANCEMENT] Upgrade leek to 0.0.6. #934
  • [BUGFIX] leek upgrade fixes #642, #709
  • [ENHANCEMENT] Allow disabling of automatic fingerprinting. #930
  • [ENHANCEMENT] Update ember-cli-shims to add ember-data shim. #941
  • [ENHANCEMENT] Update default jshint settings to require importing Ember. #941
  • [ENHANCEMENT] Bring generators in-house via blueprints. #747
  • [BUGFIX] Only process applicaiton code with ES3SafeFilter. #949
  • [ENHANCEMENT] Separate applicaiton code from vendor code. Generate /assets/vendor.js for vendored code. #949
  • [ENHANCEMENT] Provide registry access from EmberApp. #955
  • [BUGFIX] Ensure that EmberENV is setup (to allow enabling flagged features). #957


  • [ENHANCEMENT] less CPU intensive watching thanks to @krisselden’s https://github.com/krisselden/broccoli-sane-watcher and @amasad’s https://github.com/amasad/sane
  • [BUGFIX] Upgrade broccoli-es6-concatenator to 0.1.6 to fix a concatenation issue. broccoli-es6-concatenator#17
  • [BUGFIX] prevent pointless event emitter memory leak warning #850
  • [ENHANCEMENT] add and es3 safe transpile step: specifically promise.catch and promise.finally -> promise[‘catch’] & promise[‘finally’]. In addition we cover afew more variables see: https://github.com/stefanpenner/es3-safe-recast #823
  • [ENHANCEMENT] Load the vendor.css in the rendered HTML. #728
  • [ENHANCEMENT] Allow testem port to be specified when running ember test --server. #729
  • [BUGFIX] Use EMBER_ENV if specified in ENV_VARIABLES EMBER_ENV=production ember build. #753
  • [ENHANCEMENT] If both EMBER_ENV and –environment are specified, use EMBER_ENV. #753
  • [ENHANCEMENT] Update broccoli-jshint to 0.5.0 (more efficient caching for faster rebuilds). #758
  • [ENHANCEMENT] Ensure that the app/templates/components directory is created automatically. #761
  • [BUGFIX] For ember-init, Use app name if specified, over package.json or cwd name. #792
  • [ENHANCEMENT] Add support for Web Notifications for QUnit test suite with ember-qunit-notifications. #804
  • [BUGFIX] Ensure that files in app/ are JSHinted properly. #832
  • [ENHANCEMENT] Update ember-load-initializers to 0.0.2.
  • [ENHANCEMENT] Add broccoli-asset-rev for fingerprinting + source re-writing. #814
  • [BUGFIX] Prevent broccoli from watching node_modules/ember-cli/lib/broccoli/. #857
  • [BUGFIX] Prevent collision between running ember server and ember test --server simultaneously. #862
  • [ENHANCEMENT] Show timing and slow tree listing for each rebuild. #860 & #865
  • [BUGFIX] Disable wrapInEval by default. #866
  • [ENHANCEMENT] Allow passing tests and hinting to new EmberApp(). #876
  • [BUGFIX] Prevent slow tree printout during ember test --server from bleeding through testem UI.#877
  • [ENHANCEMENT] Remove unused vendor/_loader.js file. #880
  • [ENHANCEMENT] Allow disabling JSHint tests from within QUnit UI. #878
  • [ENHANCEMENT] Upgrage ember-resolver to 0.1.1 (and lock down version in bower.json). #885


  • [FEATURE] The baseURL in your environment.js now gets the leading and trailing slash automatically if you omit them. #683
  • [FEATURE] The development server now serves the site under the specified baseURL. #683
  • [FEATURE] Expose server: Bring back the API stub’s functionality, give users the opportunity to add their own middleware. #683
  • [ENHANCEMENT] project.require() can now be used to require files from the user’s project. #683
  • [ENHANCEMENT] Plugins can fall back to alternate file extensions (i.e scss, sass)
  • [BUGFIX] Fix incorrect generation of all vendor/ assets in build output. #645
  • [ENHANCEMENT] Update to Broccoli 0.12. Prevents double initial rebuilds when running ember server. #648
  • [BREAKING ENHANCEMENT] The generated app.js and app.css files are now named for your application name. #638
  • [ENHANCEMENT] added first iteration of a slow but thorough acceptance test. A new app is generated, depedencies resolve, and the test for that base app are run. #614
  • [ENHANCEMENT] Use handlebars-runtime in production. #675
  • [BUGFIX] Do not watch vendor/ for changes (watching vendor drammatically increases CPU usage). #693
  • [ENHANCEMENT] Minify CSS #688
  • [ENHANCEMENT] Allows using app.import for things other than JS and CSS (i.e. fonts, images, json, etc). #699
  • [BUGFIX] Fix ember --help output for test and version commands. #701
  • [BUGFIX] Fix package.json preprocessor dependencies not being included in the registry. #703
  • [BUGFIX] Update testem version to fix error thrown for certain assertions when running ember test, also fixes issue with ember test --server in Node 0.10. #714


  • [BUGFIX] ` ENV.LOG_MODULE_RESOLVER` must be set pre-1.6 to get better container logging.
  • [FEATURE] Added support for ember-scripts preprocessing.
  • [ENHANCEMENT] Refactor blueprint.js to remove unnecessary variable assignment, change double iteration to simple reduce, and remove function that only swapped arguments and called through. #537
  • [ENHANCEMENT] Refactor test-loader.js for readability and to prevent unnecessary iterations #524
  • [ENHANCEMENT] Remove Ember.setupForTesting and Router.reopen({location: 'none'}); from test helpers #516.
  • [ENHANCEMENT] Update loom-generators-ember-appkit to ^1.1.1.
  • [BUGFIX] Whitelist ic-ajax exports to prevent import validation warnings. #533
  • [BUGFIX] ember init fails on NULL_PROJECT (#546)
  • [ENHANCEMENT] Files added by ember-cli should not needed to be specified in Brocfile.js. #534
  • [ENHANCEMENT] Ensure minified output is using compress and mangle options with uglify-js. #564
  • [BUGFIX] Update to Broccoli 0.10.0. This should resolve the primary issue ember-cli has on Windows. #578
  • [ENHANCEMENT] Always Precompile Handlebars templates. #574
  • [ENHANCEMENT] Update to Broccoli 0.11.0. This provides better timing information for Watcher. #587
  • [ENHANCEMENT] Track rebuild timing. #588
  • [ENHANCEMENT] Remove global defined helpers in favor of http://api.qunitjs.com/equal http://api.qunitjs.com/strictEqual/, etc. #579
  • [BREAKING BUGFIX] No longer rely on broccoli-bower to automatically import vendored files. Use app.import to import dependencies and specify modules to whitelist. #562
  • [ENHANCEMENT] Removed proxy-url and proxy-host parameters and introduced proxy param with full proxy url. (#567)
  • [ENHANCEMENT] Update to jQuery 1.11.1.
  • [ENHANCEMENT] When using non-NPM installed package (aka “running on master”) the branch name and SHA are now printed along with the prior version number. #634


  • [BUGFIX] The blueprinted application’s package.json forces an older version of ember-cli. Fixed in #518.


  • Changes to index.html: Script tags were moved into body, ENV and the app are now defined in the same script tag.
  • patch to quickfix some broccoli + Windows IO issues. We expect a proper solution soon, but this will hold us over (#493).
  • Add a custom watcher to make broccoli more usable on windows by catching file errors (493).
  • Add ember test with Testem integration (388).
  • some improvements to bower dependency management, unfortunately until bower.json stabilizes broccoli-bower stability is at the whim of bower component authors.
  • introduce maintainable + upgradable ember app specific brocfile filter (396)
  • ember cli now attempts to use the project-local ember-cli if available, this should help with people who have multiple versions of the cli installed. (5a3c9a)
  • Complete restructuring of how ember-cli works internally
  • ember help now offers nicely colored output
  • Extracts initializers autoloading into bower package (#337)
    • locks it to version 0.0.1
  • Introduces broccoli-bower (#333)
    • locks it to version 0.2.0
  • Fix issue where app.js files are appended to tests.js (#347)
  • upgrade broccoli to 0.9.0 v0.9.0 brocfile changes
  • Use configuration from config/environments.js to pass options to Ember.Application.create. (#370)
  • Adds per command help output (#376)
  • Ensures that the broccoli trees are cleaned up properly. (#444)
  • Integrate leek package for ember-cli usage analytics reporting. (#448)
  • Generate current live build to tmp/output/ when running ember server. This is very useful for debugging the current Broccoli tree without manually running ember build. (#457)
  • Added ember test --server to run the testem command line server. ember test --server will automatically re-run your tests after a rebuild. #474
  • Add JSHinting for app/ and test/ trees when building in development. This generates console logs as well as QUnit tests (so that ember test shows failures). #482
  • Use the name specified in package.json while doing ember init. This allows you to use a different application name than your folder name. #491
  • Allow disabling live reload via ember server --live-reload=false. #510


  • Adds ES6 import validation (#209)
  • CSS broccoli fixes (#325)
  • Speed up boot (#273)


  • Makes sure that user cannot create an application named test(#256)
  • Adds broccoli-merge-trees dependency and updates Brocfile to use it
  • Locks blueprint to particular version of ember-cli, broccoli & friends:
    • ember-cli 0.0.21
    • broccoli (v0.7.2)
    • broccoli-es6-concatenator (v0.1.4)
    • broccoli-static-compiler (v0.1.4)
    • broccoli-replace version (v0.1.5)


  • Use loader.js from bower (0c1e8d28)
  • Drops implementation files (54df0288)
  • Drop boilerplate tests (c6f7475e)
  • Use named-amd version of ic-ajax (#225)
  • Separate tests and app code. Tests are now within ‘assets/tests.js’ (#220).
  • Implement --proxy-port and --proxy-host parameters to ember server command (#40)
  • Add support for .ember-cli file to provide default flags to commands (7b90bd9)
  • Ember initializers are required automatically (#242)
  • Supports alternate preprocessors (eg. broccoli-sass vs. broccoli-ruby-sass) (59ddbd)
  • Also exposes registerPlugin method on preprocessor module that allows anyone to register additional plugins (59ddbd)


  • Run tests through /tests.
  • Integrate ember-qunit.
  • Makes sure livereload reports error from watcher (a1d447fe)
  • Support multiple CSS Preprocessors (LESS, Sass and Stylus)
  • upgrade broccoli to 0.5.0.