Harnessing Ember Octane’s Tracked Properties: A Practical Guide
Learn how Ember Octane’s @tracked decorator simplifies reactivity, with a step‑by‑step counter example, common pitfalls, and best‑practice tips for production code.
15 Jul 2025, 06:38 UTC

Why Tracked Properties Matter
When building Ember Octane applications, reactivity is the glue that keeps the UI in sync with data. In earlier Ember versions developers relied on @tracked on legacy objects or manual getters/setters. Octane simplifies this by providing a @tracked decorator that works directly on native ES classes. This eliminates boilerplate, keeps your components lean, and guarantees that any mutation of a tracked property automatically triggers a re‑render.
Getting Started: A Minimal Counter Component
Generate a new Octane app if you haven’t already:
ember new tracked-demo cd tracked-demo ember serveCreate a component that will display and increment a counter. Run:
ember generate component counterEdit
app/components/counter.jsto add a tracked property:import Component from '@glimmer/component'; import { tracked } from '@glimmer/tracking'; export default class CounterComponent extends Component { @tracked count = 0; increment() { this.count += 1; } }Update the template
app/templates/components/counter.hbs:<div> <button type="button" {{on "click" this.increment}}>Increment</button> <p>Current count: {{this.count}}</p> </div>Refresh the page. Clicking the button updates the count and the paragraph instantly – no manual DOM manipulation required.
How Ember Detects Changes
The @tracked decorator tells Ember’s reactivity engine to watch the property for assignments. When this.count is reassigned, Ember records the change and schedules a re‑render of the component. This is a shallow comparison: Ember notes that the reference to count changed, not the value itself. Consequently, mutating an object in place (e.g., this.obj.prop = 5) won’t trigger a re‑render unless the object reference changes.
Common Pitfalls and Trade‑Offs
- Forgetting
@tracked: The component will render once, but subsequent changes won’t appear. Ember will silently ignore the mutation, leading to confusing bugs. Use theember-tracked-propertieslinter rule or the Ember Inspector to catch missing decorators. - Large Tracked Objects: Tracking every field in a massive object forces Ember to perform deep change detection each time the reference changes. This can degrade performance. Prefer immutable patterns: replace the object entirely or track only the fields that drive UI updates.
- Legacy Ember Objects: Classic Ember objects use
getandset. Mixing them with Octane’s@trackedcan cause confusion because the two systems handle reactivity differently. - In‑Place Mutations: If you mutate nested properties of a tracked object, Ember won’t notice. Either replace the entire object or create a separate tracked property for the nested value.
Verifying Tracking in the Browser
Two handy tools help confirm that tracking works as expected:
- Ember Inspector – Tracked Properties Panel: Open DevTools, click the Ember tab, and inspect the component. The panel lists all tracked properties and shows the current value.
- Component Metadata: In the console, grab a reference to the component instance and inspect its
trackedPropertiesmap:let comp = document.querySelector('counter').component; console.log(comp.trackedProperties);
Next Steps for Production‑Ready Code
Use
@trackedsparingly: only on values that directly affect rendering. For derived data, compute it in a getter or a computed macro.Adopt immutable updates for complex state: replace objects instead of mutating them in place to keep tracking reliable.
Enable the
ember-tracked-propertieslinter rule in your.eslintrc.jsto catch missing decorators early:"ember-tracked-properties": "error"Run performance tests on components that track large data structures. If you notice lag, refactor to track only the minimal subset of properties.
Stay updated with Ember releases: the tracking implementation evolves, and newer releases may introduce optimizations or deprecations.
Conclusion
Tracked properties are a powerful feature that streamlines reactivity in Ember Octane. By decorating the right properties, you eliminate boilerplate, reduce the risk of silent bugs, and keep your UI responsive. Remember the trade‑offs—especially around large objects and in‑place mutations—and use tooling to verify tracking. With these practices, you’ll harness Ember’s reactive engine to build clean, maintainable applications.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.