diff --git a/app/assets/javascripts/discourse/controllers/avatar_selector_controller.js b/app/assets/javascripts/discourse/controllers/avatar-selector.js.es6
similarity index 86%
rename from app/assets/javascripts/discourse/controllers/avatar_selector_controller.js
rename to app/assets/javascripts/discourse/controllers/avatar-selector.js.es6
index 6c3d6d9ab..ed165e45c 100644
--- a/app/assets/javascripts/discourse/controllers/avatar_selector_controller.js
+++ b/app/assets/javascripts/discourse/controllers/avatar-selector.js.es6
@@ -7,7 +7,7 @@
   @uses Discourse.ModalFunctionality
   @module Discourse
 **/
-Discourse.AvatarSelectorController = Discourse.Controller.extend(Discourse.ModalFunctionality, {
+export default Discourse.Controller.extend(Discourse.ModalFunctionality, {
 
   actions: {
     useUploadedAvatar: function() { this.set("use_uploaded_avatar", true); },
diff --git a/app/assets/javascripts/discourse/controllers/header_controller.js b/app/assets/javascripts/discourse/controllers/header.js.es6
similarity index 94%
rename from app/assets/javascripts/discourse/controllers/header_controller.js
rename to app/assets/javascripts/discourse/controllers/header.js.es6
index c037cafc0..4bd9934ac 100644
--- a/app/assets/javascripts/discourse/controllers/header_controller.js
+++ b/app/assets/javascripts/discourse/controllers/header.js.es6
@@ -6,7 +6,7 @@
   @namespace Discourse
   @module Discourse
 **/
-Discourse.HeaderController = Discourse.Controller.extend({
+export default Discourse.Controller.extend({
   topic: null,
   showExtraInfo: null,
   notifications: null,
diff --git a/app/assets/javascripts/discourse/ember/resolver.js b/app/assets/javascripts/discourse/ember/resolver.js
index a28574b29..0f6f59459 100644
--- a/app/assets/javascripts/discourse/ember/resolver.js
+++ b/app/assets/javascripts/discourse/ember/resolver.js
@@ -9,11 +9,29 @@
 **/
 Discourse.Resolver = Ember.DefaultResolver.extend({
 
+  /**
+    For our ES6 modules, Discourse standardizes on dashed, lower case names.
+    This method converts camelCase to that format.
+
+    @method normalizeName
+    @param {String} name to convert
+    @returns {String} the converted name
+
+  **/
+  normalizeName: function(name) {
+    return name.replace(/([a-z])([A-Z])/g, '$1-$2').replace('_', '-').toLowerCase();
+  },
+
   resolveController: function(parsedName) {
-    var moduleName = "discourse/controllers/" + parsedName.fullNameWithoutType,
+    var normalized = this.normalizeName(parsedName.fullNameWithoutType),
+        moduleName = "discourse/controllers/" + normalized,
         module = requirejs.entries[moduleName];
 
     if (module) {
+      if (normalized !== parsedName.fullNameWithoutType) {
+        Em.Logger.error(parsedName.fullNameWithoutType + " was used to look up an ES6 module. You should use " + normalized+ " instead.");
+      }
+
       module = require(moduleName, null, null, true /* force sync */);
       if (module && module['default']) { module = module['default']; }
     }
diff --git a/app/assets/javascripts/discourse/routes/preferences_routes.js b/app/assets/javascripts/discourse/routes/preferences_routes.js
index eae59f72e..e60da21e5 100644
--- a/app/assets/javascripts/discourse/routes/preferences_routes.js
+++ b/app/assets/javascripts/discourse/routes/preferences_routes.js
@@ -18,18 +18,17 @@ Discourse.PreferencesRoute = Discourse.RestrictedUserRoute.extend({
 
   actions: {
     showAvatarSelector: function() {
-      Discourse.Route.showModal(this, 'avatarSelector');
+      Discourse.Route.showModal(this, 'avatar-selector');
       // all the properties needed for displaying the avatar selector modal
-      var avatarSelector = this.modelFor('user').getProperties(
+      this.controllerFor('avatar-selector').setProperties(this.modelFor('user').getProperties(
         'username', 'email',
         'has_uploaded_avatar', 'use_uploaded_avatar',
-        'gravatar_template', 'uploaded_avatar_template');
-      this.controllerFor('avatarSelector').setProperties(avatarSelector);
+        'gravatar_template', 'uploaded_avatar_template'));
     },
 
     saveAvatarSelection: function() {
       var user = this.modelFor('user');
-      var avatarSelector = this.controllerFor('avatarSelector');
+      var avatarSelector = this.controllerFor('avatar-selector');
       // sends the information to the server if it has changed
       if (avatarSelector.get('use_uploaded_avatar') !== user.get('use_uploaded_avatar')) {
         user.toggleAvatarSelection(avatarSelector.get('use_uploaded_avatar'));
diff --git a/test/javascripts/controllers/avatar_selector_controller_test.js b/test/javascripts/controllers/avatar_selector_controller_test.js
index 680b8b622..b9385564c 100644
--- a/test/javascripts/controllers/avatar_selector_controller_test.js
+++ b/test/javascripts/controllers/avatar_selector_controller_test.js
@@ -4,10 +4,10 @@ var avatarSelector = Em.Object.create({
   uploaded_avatar_template: "//cdn.discourse.org/uploads/meta_discourse/avatars/093/607/185cff113e/{size}.jpg"
 });
 
-module("Discourse.AvatarSelectorController");
+module("controller:avatar-selector");
 
 test("avatarTemplate", function() {
-  var avatarSelectorController = testController(Discourse.AvatarSelectorController);
+  var avatarSelectorController = controllerFor('avatar-selector');
   avatarSelectorController.setProperties(avatarSelector);
 
   equal(avatarSelectorController.get("avatarTemplate"),
diff --git a/test/javascripts/controllers/header_controller_test.js b/test/javascripts/controllers/header_controller_test.js
index e64842778..73db59ffe 100644
--- a/test/javascripts/controllers/header_controller_test.js
+++ b/test/javascripts/controllers/header_controller_test.js
@@ -1,4 +1,4 @@
-module("Discourse.HeaderController");
+module("controller:header", "Header Controller");
 
 test("showNotifications action", function() {
   var resolveRequestWith;
@@ -7,7 +7,7 @@ test("showNotifications action", function() {
   });
 
 
-  var controller = Discourse.HeaderController.create();
+  var controller = controllerFor('header');
   var viewSpy = {
     showDropdownBySelector: sinon.spy()
   };
diff --git a/test/javascripts/ember/resolver_test.js b/test/javascripts/ember/resolver_test.js
index 904418223..a0ebd40a8 100644
--- a/test/javascripts/ember/resolver_test.js
+++ b/test/javascripts/ember/resolver_test.js
@@ -14,6 +14,11 @@ function setTemplates(lookupStrings) {
   });
 }
 
+function normalized(input, expected, desc) {
+  var resolver = Discourse.Resolver.create({namespace: Discourse});
+  equal(resolver.normalizeName(input), expected, desc);
+}
+
 module("Discourse.Resolver", {
   setup: function() {
     originalTemplates = Ember.TEMPLATES;
@@ -29,6 +34,12 @@ module("Discourse.Resolver", {
   }
 });
 
+test("normalizeName", function() {
+  normalized('header', 'header', 'a single word stays the same');
+  normalized('avatarSelector', 'avatar-selector', 'camel case is converted to dashed');
+  normalized('avatar_selector', 'avatar-selector', 'underscores are converted to dashes');
+});
+
 test("finds templates in top level dir", function() {
   setTemplates([
     "foobar",