Native Classes, Tracked Properties, Angle-Brackets
Ember Octane — What's New
Octane is Ember's modern programming model — native ES classes, `@tracked` reactivity, Glimmer components, and angle-bracket invocation.
What you'll learn
- Use native classes instead of `Ember.Object.extend`
- Use `@tracked` instead of computed properties
- Use `<MyComponent />` instead of `{{my-component}}`
Ember Octane is the major redesign that shipped in 3.15 and is the default in v5+. If you read old tutorials with Ember.Component.extend(...) and Ember.computed, you are looking at the classic era. Everything new uses Octane.
Classes Instead of .extend
// classic (don't use)
import Component from '@ember/component';
export default Component.extend({
count: 0,
actions: {
inc() { this.incrementProperty('count'); },
},
});
// Octane
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';
export default class Counter extends Component {
@tracked count = 0;
@action inc() { this.count++; }
} Native classes mean editor support, TypeScript, decorators, and predictable this.
@tracked Instead of Computed
// classic
firstName: '',
lastName: '',
fullName: computed('firstName', 'lastName', function () {
return `${this.firstName} ${this.lastName}`;
}),
// Octane — auto-tracked getter
@tracked firstName = '';
@tracked lastName = '';
get fullName() {
return `${this.firstName} ${this.lastName}`;
} @tracked marks a field as reactive. Any getter that reads tracked state is automatically reactive — no dependency lists.
Angle-Bracket Components
{{! classic curly invocation }}
{{my-component name=this.name onSave=(action "save")}}
{{! Octane angle-brackets }}
<MyComponent @name={{this.name}} @onSave={{this.save}} /> Angle brackets clarify what is HTML vs a component, and @arg clearly marks arguments.