Components patterns in Ember.js

Maciej Kwaśniak
Dec 10, 2018 · 3 min read

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


The Macsour blog

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

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