Ember Octane — What's New

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.

4 min read Level 2/5 #ember#octane#modernization
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.

The Router DSL →