---
title: From Ember-Rails to Ember CLI
teaser: Migrate an Ember application from Ember-Rails to Ember CLI.
tags: web,ember,javascript
author: Blake Williams
published_on: 2015-01-09
---

The majority of Ember applications I've worked on have been powered by the
[Ember-Rails] gem. Ember-Rails is great but can make your Ember app feel like a
second class citizen when it's just as important as the Rails <abbr
title="Application Programming Interface">API</abbr> that powers it.

[Ember CLI] solves this issue by separating your Ember application from Rails
and providing an environment to develop, build, and test your Ember
applications.

[Ember-Rails]: https://github.com/emberjs/ember-rails
[Ember CLI]: http://www.ember-cli.com/

## From globals to modules

The biggest change when migrating to Ember CLI was moving away from a global
`App` namespace to [ES6 modules]. With Ember-Rails `app.coffee` would look like
this:

[ES6 Modules]: http://esnext.github.io/es6-module-transpiler/

```coffeescript
window.App = Ember.Application.create
  rootElement: "#ember_app_container"
```

Ember CLI uses ES6 modules to import dependencies and export functions and
objects:

```coffeescript
`import Ember from "ember";`

App = Ember.Application.extend
  rootElement: "#ember-app-container"

`export default App;`
```

Unfortunately CoffeeScript doesn't support ES6 module syntax yet, so we have to
embed JavaScript directly using backticks to import and export modules.

Instead of creating our `App` instance directly we export it and Ember CLI will
instantiate it for us. If we were using JavaScript instead of CoffeeScript we
could export it directly instead of having to assign it to a variable:

```javascript
import Ember from "ember";

export default Ember.Application.extend({
  rootElement: "#ember-app-container"
});
```

Ember CLI also comes with its own [custom resolver] that takes advantage of ES6
modules, giving us different filename conventions. Underscores are replaced with
dashes, `.js.coffee` is replaced with just `.coffee` if you're using
CoffeeScript, and the "\_type" suffix is removed entirely, e.g.:
`controllers/application_controller.js.coffee` would become
`controllers/application.coffee`.

[custom resolver]: http://www.ember-cli.com/#using-modules

These changes are necessary since ES6 modules use the relative path and filename
to generate the module name. For example, `controllers/application.coffee` would
export to a module named `your-app-name/controllers/application`.

## Testing

Ember CLI ships with a test environment with QUnit as the default testing
framework. When we converted from Ember-Rails we were using Mocha and were
forced into adopting QUnit.

Fortunately [QUnit-BDD] allowed us to get away with minor changes to our test
suite such as `eq` becoming `equal` and having to write our own `include`
helper.

Now that Mocha is supported in Ember CLI through [ember-cli-mocha] we can skip
QUnit/QUnit <abbr title="Behavior Driven Development">BDD</abbr> entirely.

[ember-cli-mocha]: https://github.com/switchfly/ember-cli-mocha
[QUnit-BDD]: https://github.com/square/qunit-bdd

## Deploying

After the migration was completed and the tests were passing we needed to figure
out how to deploy it. We ended up going with Heroku and this
[Ember CLI buildpack] that builds and serves our application for us.

[Ember CLI buildpack]: https://github.com/tonycoco/heroku-buildpack-ember-cli

We took advantage of Ember CLI's `config/environment.js` file to point
Ember-Data to different endpoints based on the environment the application is
built/running in.

```coffeescript
if environment == "staging"
  ENV.API_HOST = "https://api-staging.herokuapp.com"

if environment == "production"
  ENV.API_HOST = "https://api.herokuapp.com"
```

We import these values into `app/adapters/application.coffee` as `config` and
set the adapters `host` property.

```coffeescript
`import DS from "ember-data";`
`import config from "../config/environment";`

ApplicationAdapter = DS.ActiveModelAdapter.extend
  host: config.API_HOST

`export default ApplicationAdapter`
```

Now every time we use the adapter the host is set for us based on the environment.

## Wrapping up

Ember CLI is still young and has a few bumps to smooth out but also has some
advantages over other options with fast incremental builds, live reload support,
and the ability to extend Ember and Ember-CLI through addons.

Best of all, Ember CLI allows us to separate our front-end from our <abbr
title="Application Programming Interface">API</abbr> and makes Ember feel like a
first class citizen instead of an afterthought.
