Published in


Components patterns in Ember.js

As an Ember developer, you are probably familiar with components. Thanks to them you can split your code into meaningful parts. Unfortunately, it’s not always obvious how they should look like, and which pattern should you use. This snippet should let you better understand what kind of components patterns you can use to be the best match for your case.

Here are all the components patterns I found in the Ember community, that I think is good to know.

Components patterns

Presentational component

Photo by Joshua Hoehne on Unsplash

This is the basic type of component. It used for presenting, formatting data. It takes some properties and displays them in a more meaningful way. It shouldn’t be responsible for data fetching or business logic. One good example can be a component for displaying a user’s avatar.

Example definition:

// user-avatar/template.hbs
<img src={{user.avatarUrl}}>

Call API example:

{{user-avatar user=user}}


Contextual component

Photo by michael podger on Unsplash

These components can be used as a wrapper eg. for markup. They can act like any other component type. The only difference is that they can pass content inside of the block to a specific place in the component using the {{yield}} statement.

Example definition:

// page-header/template.hbs
<div class="jumbotron">
<h1>Hello, world!</h1>

Call API example:

How are you?


Container component

Photo by Guillaume Bolduc on Unsplash

This pattern is used for data manipulation, actions handling and all the business logic around. For example, it can fetch the user and format the content using presentational components. Container component can also act as the contextual component, allowing you to overwrite the content and markup by passing a block.

Example definition:

// user-profile/component.js
import Component from '@ember/component';
import { inject as service } from '@ember/service';
import { computed } from '@ember/object';
export default Component.extend({
store: service(),
id: null,

user: computed('id', function() {
return id ?'user', : null;
// user-profile/template.hbs
{{#if hasBlock}}
{{yield user}}
{{user-avatar user=user}}

Call API example:

{{#user-profile id=7 as |user|}}


Composable component (aka Higher-Order Component)

Photo by Rick Mason on Unsplash

Its role is to deliver to you meaningful components/parts from which you can build your business logic and features but also serves as a great extension for container components. They should still stay flexible so you can add your own markup or modify behaviors. This kind of components can be used in a top-level template where you define your application layout but can be also used to form another component.

Example definition:

// articles-list/template.hbs
{{yield (hash
list=(component "articles-list/list" articles=articles)
pagination=(component "articles-list/pagination")

Call API example:

{{#articles-list articles=user.articles as |articlesList|}}
{{#articlesList.components.list as |list|}}
{{#list.components.item as |article|}}
<p class="lead">{{article.body}}</p>


More about composable components soon in next articles :)

Of course, this is just an outline of these patterns but the point is to give an overview of which components pattern we can use during the development process of our application.

Any questions?
Twitter: theMacsour

Hire me as your next frontend engineer!

Check out my projects, experience, and ask me a question on

 by the author.




Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Maciej Kwaśniak

Maciej Kwaśniak

Ember.js Expert | Hire me!

More from Medium

Fix Windows 10/11 Icons Not Showing Up / Working as Expected

Introduction to Type systems

5 Major Benefits of Using Ember JS for Web Development

Being a dumbass is a human right — Part 2