This guide is for developers who already know Ember, and who want to learn the new concepts introduced by Octane, Ember's first Edition.
If you're new to Ember, we recommend starting with the Quick start and Tutorials.
What is Ember Octane?
Over the past few years, many new features have been added to Ember with the goal of introducing a new programming model for the framework. This new model brings major gains in productivity and performance, incrementally via a series of minor (non-breaking) releases. This allows for new apps to have the best features enabled automatically, while teams working on existing apps can migrate over time, while still keeping their apps up-to-date with the latest release.
Here are some of the core features in Octane:
- Native JavaScript classes, unlocking simpler syntax, faster performance, and better interop with the wider ecosystem.
- Decorators for customizing the behavior of components and other classes.
- Tracked properties, a type of decorator that simplifies keeping the DOM up-to-date with JavaScript changes.
- Async functions (
async
/await
) for authoring asynchronous code. - Importing npm packages with zero additional configuration.
- Glimmer components, including
- "Outer HTML" templates that support fragments and easily customizing the root element.
- Customizable DOM attributes with
...attributes
. <AngleBracket>
syntax for better readability.- Modifiers, which unify the experience of writing code that interacts with the DOM.
Just as important is what we're removing from the Ember experience. These features below will keep working through the rest of Ember 3, but you won't have to use them if you don't want to.
These have been replaced or made optional in Octane:
- jQuery. For DOM interaction, developers should use templates or native DOM APIs.
- Non-native classes. Octane apps say goodbye to
extend()
,create()
, and mixins, and use Native Classes instead. - Computed properties and observers, and other legacy features of the Ember
object model are replaced by
@tracked
. - Curly component invocation of components, eliminating the ambiguity in templates between values and DOM creation. Use Angle Brackets instead.
- The run loop. App developers should never have to write code that interacts with the Ember run loop, even in tests.
- "inner HTML" components, and the confusing JavaScript API used to
configure a component's root element, like
tagName
,classNameBindings
, etc. Now, there's no wrapping element.
Again, note that these features will continue to work for apps that need them. An edition is not a breaking change, just a minor release. But for someone starting a new Ember app today, this is complexity they can safely skip learning.
Creating a New App
To create a new app that has every Octane feature enabled, first make sure you have the latest Ember CLI version installed:
npm uninstall ember-cli
npm install -g ember-cli
Then, create your app:
ember new my-app-name
The remaining sections in this guide will go into details about how to upgrade each individual feature. There's a lot to learn here, but remember, you can gradually adopt these features in existing apps. Everything you used to do will also work all the way through the rest of Ember 3, since Ember follows SemVer strictly.
If you need any help, check out the chat and forums. If you spot something to improve in this guide, you can help out by filing an issue or a PR. Thank you!
Octane upgrade strategy
There are two areas of focus for upgrading to Octane: learning, and implementing.
Learning
We recommend that all developers go through the Quick Start Tutorial to learn the fundamentals of Octane, and then the main Tutorial.
Along the way, you might need to study up on Native JavaScript Classes too. Otherwise, it may be confusing about which parts of code are special to Ember, and which are not.
If you work on a team of developers, it may be useful to have one developer go through the tutorials, try doing a small thing, and then demo that to the rest of the team. After everyone has had a chance for hands-on learning, schedule a meeting to plan how you want to proceed.
By design, migrating to Octane can be done in pieces. It doesn't require a big-bang refactor. If you need advice, visit the forums or the Ember Discord (in Discord you can use the #topic-octane-migration
channel).
Implementing
- Follow the regular upgrade steps to update your app to at least version
3.15
. - Run your tests to make sure everything still works as expected.
- Run
npx @ember/octanify
to add any missing Octane related dependencies and enable the set of Octane optional features. - Create a new component in your app, and experiment!
ember g component
will give you just a test and a template. Adding-gc
to the command will generate the JavaScript class too. Try adding a button with an action. - Try refactoring one existing component to use Octane style. Check out the Cheat Sheet and Edition's Deep Dive for some pointers.
- Review the refactoring checklist below to create a plan for handling existing code. Note that some steps have codemods available!
If you need help along the way, visit the Ember Community chat and forums.
Deprecations that matter for Octane
By default, Octane does not include jQuery. Continuing to use jQuery in your app will not conflict with Octane features, however you should follow the deprecation instructions for jquery-apis
if you need to keep using it.
Optional features in Octane
A fully-Octane app has the following configuration in config/optional-features.json
:
{
"application-template-wrapper": false,
"default-async-observers": true,
"jquery-integration": false,
"template-only-glimmer-components": true
}
As mentioned above, we recommend that you use npx @ember/octanify
to ensure these flags are set to the appropriate values. To learn what each option does, check out the Optional Features guide.
Refactoring checklist
For many of the optional features, the thing they affect the most is what you see in your newly-created files, not within your existing code. Your app will keep working, even if you haven't refactored code to use Octane's features yet. Making new files in the Octane style is good place to start, but eventually you should refactor existing code so that your app follows one main programming model, not a mixture of Octane and Classic. Following a refactoring plan will help with onboarding new developers, and minimize flipping back and forth between different versions of the Ember Guides.
There's no one-size-fits-all strategy, but here is a checklist you can adapt, once you're familiar with what Octane has to offer:
- Whenever you make new components, use Octane-style components. Create them with
ember generate component my-component -gc
. They can coexist in the same app with older components. Meanwhile, go through the rest of the steps below. - Convert curly bracket components (
{{my-component}}
) to Angle Brackets (<MyComponent />
), using theember-angle-brackets-codemod
. Angle Brackets are feature of Ember since 3.4 that does not change a component's behavior. Read the Angle Bracket Syntax guide for some examples and more in-depth information. - Use Named Arguments and
this
in your templates, by running theember-no-implicit-this-codemod
. Component behavior should not change. - Use the
ember-native-class-codemod
on your non-component JavaScript files. - Refactor some components to use Glimmer Components. Good components to refactor first are those that do not rely on two-way bindings, computed properties, or observers. These components will serve as examples that your coworkers can refer back to.
- Now, you have a choice to make, and the right answer varies based on how your team operates and what your app is like. Consider which path has the least mental overhead for your engineering team, including both experienced and beginner Ember developers.
- The first option is, you could leave most older components as-is, and gradually convert them to Octane style components whenever the course of your work requires you to edit those files. The advantage is that it is very easy for everyone to tell whether a component is classic or Octane. The disadvantage is that muscle memory for Objects vs Classes is tough to overcome.
- The second option is, you could run the
ember-native-class-codemod
for all remaining components. This will turn them into components that import from@ember/component
, retaining all the same APIs that classic components have, but just represented in a Native Class syntax. Then, following a similar pattern as option number one, you could convert them to import from@glimmer/component
as you work. The advantage is that everyone gets used to working with Native Classes right away. The disadvantage is that the visual differences between a Native Class@ember/component
and a@glimmer/component
are subtle, and time could easily be lost to mistakes like trying to usedidInsertElement
on the@glimmer/component
.