Ember.js Octane vs Classic Cheat Sheet

This guide is a cheat sheet for using Ember.js Octane. It doesn't cover everything, but it should get you started!
PRs welcome at the GitHub repository

For in-depth information about the upgrade paths and differences introduced in Octane, see The Octane Upgrading Guide.

Generating Files

Use an option to generate a component's JavaScript

In classic Ember, "ember generate component" created three files: the template, a JavaScript file, and a test. In Octane, "ember generate component" creates only a template. If you want the backing JavaScript Class as well, include an option.

Classic


          

Octane


          

Component templates and JavaScript are in the same directory

The location of component templates has changed in Octane. This is known as "template co-location."

Classic


          

Octane


          

Component Templates

Angle Brackets Component Invocation

Angle brackets are a way to invoke components in a template file. There's no change in behavior. Learn more about features and using codemods to update your existing components.

Classic


          

Octane


          

Inline vs block components

Angle brackets components can be used as either inline or block components. There's no change in behavior. {{yield}} looks and works the same. Learn more about features and using codemods to update your existing components.

Classic


          

Octane


          

Nesting components in your file structure

You can nest components in your file structure, and use them in a template with Angle Brackets invocation. There's no change in behavior.

Classic


          

Octane


          

Using named arguments

If a property was received from a parent component, refer to it with an @. There's no change in behavior. (Learn more)

Classic


          

Octane


          

Using own properties

If a property is defined in the JavaScript file for this component's template, use a "this" when you refer to it. There's no change in behavior. Learn more about features and using codemods to update your existing components.

Classic


          

Octane


          

Passing named arguments

When you pass an argument to a component, use an `@` symbol on the left hand side. There's no change in behavior. Learn more about features and using codemods to update your existing components.

Classic


          

Octane


          

Passing arguments defined on "this" component

If a property is coming from a template's own JavaScript file, remember to put a "this." before it and wrap it in curly braces. Learn more about features and using codemods to update your existing components.

Classic


          

Octane


          

All components are tagless

In Octane, components don't have a default wrapper anymore, so you don't need tagName! Just put the tag right in the template.

Classic


            

          

Octane


            

          

Make your own elementId

Since components are tagless, there's no elementId, but you can generate your own. This is especially helpful for creating accessible forms.

Classic


            

          

Octane


            

          

Component Properties

Component JavaScript Syntax

An Octane component imports from the @glimmer package namespace, and it uses Native Class syntax. Glimmer components have different API methods than those on the classic @ember/component. If you aren't familiar with Native Classes, first check out the the documentation on MDN . Then, learn more about Octane component classes and the Component API Documentation.

Classic


          

Octane


          

Declaring a property

Properties follow normal Native JavaScript Class syntax. Look ma, no commas!

Classic


          

Octane


          

Data Down, Actions Up

Octane components enforce "Data Down, Actions Up." That means that when data is passed down to a component, the only way to change that data is by using an action that was passed in as well. Said another way, there is no two-way binding of component arguments.

Classic


            

            

            

          

Octane


            

            

          

No more get and set on components

Octane components do not use this.get or this.set. Access and modify properties directly, the same as you would in a regular JavaScript Class.

Classic


            

Octane


            

Use @tracked and getters instead of computed properties

Label the properties that should be tracked to compute another property, which is a getter.

Classic


            
          

Octane


          

Computed decorators

For Octane, it is recommended to refactor computed properties to use tracked instead. However, there is a @computed decorator available as well.

Classic


          

Octane


          

Actions

Use @action, on, and fn instead of action

Use the @action decorator in your JavaScript to indicate functions that you want to be able to use in a template. Use those functions in the template with "on," and if you need to pass an argument to the function, use "fn" too. (Learn more)

Classic


          

Octane


          

Classic


          

Octane


          

Specifying a default value for an argument

Because arguments are read only, their values cannot be changed so no default value can be set. To have a default-value-like experience, native getters may be used.

Classic

            

          
Octane

            

          

Mixins

You cannot use mixins on anything that uses Native Class syntax (such as components that import from @glimmer/component). The replacement strategy depends on your use case. If your app depends on an addon that uses Mixins, it may be best to continue using classic components until an alternative is ready.

Classic

          
Octane

See Do you need Ember Object? for Mixin alternatives, such as utility functions, services, delegates, and class decorators.

Component Lifecycle

Using constructor instead of init.

constructor is a feature of JavaScript Native Classes, not something Ember made up. Use it instead of init. No more this.set! (Learn more)

Classic


          

Octane


          

Element Modifiers

There are three new element modifiers, {{did-insert}}, {{did-update}}, and {{will-destroy}}, that you may use to replace the classic component lifecycle hooks didInsertElement, willDestroy, and didUpdate.

In order for these modifiers to work, you need to install the @ember/render-modifiers package.


        

Use element modifiers instead of didInsertElement

Instead of writing a didInsertElement method in the JavaScript file, put the {{did-insert}} modifier in your template and say which function to call when that element is rendered. Label that function with the @action decorator. (Learn more)

Classic


            

          

Octane


            

          

Using willDestroy

willDestroy is called when the entire component's element will be destroyed, similar to willDestroyElement. You can use it as a method like below, or via a modifier similar to {{did-insert}} just above. (Learn more)

Classic


          

Octane


          

Routes

Accessing a route's model

The model used in a route template has always come from an outside context. For this reason, in Octane, refer to it as @model.

Classic


          

Octane