Using Ember Octane Tracked Properties to Simplify Reactive State
Learn how Ember Octane's tracked properties replace implicit computed property dependencies with explicit @tracked decorators and autotracking for simpler, more reliable reactive state.
15 Jun 2026, 16:51 UTC

The problem with implicit dependencies
In classic Ember, computed properties declare their dependent keys as strings. When a dependency is missed or mistyped, the UI can show stale data, and debugging requires tracing which keys actually affect the value. As applications grow, these implicit dependencies become hard to maintain.
How tracked properties change the model
Ember Octane introduced @tracked decorators and autotracking. A property marked @tracked signals to Ember that its value can change. Any getter that reads a tracked property during its execution is automatically considered dependent on that property. When the tracked value updates, Ember recomputes the getter without extra dependency strings.
Worked example: a user‑name component
Generate a component:
ember g component user-name
Replace user-name.js with:
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';
export default class UserNameComponent extends Component {
@tracked firstName = '';
@tracked lastName = '';
get fullName() {
return `${this.firstName} ${this.lastName}`.trim();
}
@action
updateFirstName(event) {
this.firstName = event.target.value;
}
@action
updateLastName(event) {
this.lastName = event.target.value;
}
}
The template user-name.hbs can bind inputs and display the name:
<label>First name:
<input value={{this.firstName}} oninput={{this.updateFirstName}} />
</label>
<label>Last name:
<input value={{this.lastName}} oninput={{this.updateLastName}} />
</label>
Hello, {{this.fullName}}!
When either input changes, the tracked property updates, autotracking notices that fullName read the changed value, and the displayed name refreshes instantly—no extra observers or dependency arrays needed.
Trade‑offs and migration considerations
- Version requirement: Tracked properties need Ember 3.13 or later. Running
ember -vshould show at least that version; otherwise the decorator will throw a runtime error. - Mental shift: Developers must stop listing dependent keys and instead rely on the getter’s read‑track pattern. Existing computed properties can coexist, but mixing them in the same class risks missing dependencies if a getter reads a tracked property while a computed property expects a string key.
- Debugging: While autotracking reduces boilerplate, tracing why a value recomputed can be less obvious than reading a dependency list. Ember’s inspector tooling can help visualize tracked property changes.
Actionable next steps
- Upgrade your Ember CLI project to >=3.13 if it isn’t already (
npm install ember-source@~3.28.0or the latest LTS). - Create a new component using the pattern above, or refactor an existing computed property by replacing it with a
@trackedfield and a getter. - Run the app (
ember serve) and verify that UI updates correspond to input changes without adding observers. - Gradually migrate other computed properties, testing each change in isolation.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.