What are Ember Pods? Ember pods are a way of structuring your project by feature, instead of type. Instead of having a directory structure with several types (controllers, models, templates...), everything is grouped around a feature (comments, posts...).

Let's take a look at the normal directory structure in our app/ folder for a basic blog with comments and posts. (If you're looking for a full featured guide on how to create a blog using Ember check out the one I did earlier last month).

The normal structure should look familiar to you.

// app/
├── app.js
├── components
├── controllers
├── helpers
├── index.html
├── models
│   ├── comment.js
│   └── post.js
├── router.js
├── routes
│   ├── comment.js
│   └── post.js
├── styles
│   └── app.css
├── templates
│   ├── application.hbs
│   ├── comment.hbs
│   ├── components
│   └── post.hbs
└── views

// tests
├── helpers
│   ├── resolver.js
│   └── start-app.js
├── index.html
├── test-helper.js
└── unit
    ├── models
    │   ├── comment-test.js
    │   └── post-test.js
    └── routes
        ├── comment-test.js
        └── post-test.js

What if we used the pod structure instead? Take a look below.

// app/
├── app.js
├── comment
│   ├── model.js
│   ├── route.js
│   └── template.hbs
├── components
├── controllers
├── helpers
├── index.html
├── models
├── post
│   ├── model.js
│   ├── route.js
│   └── template.hbs
├── router.js
├── routes
├── styles
│   └── app.css
├── templates
│   ├── application.hbs
│   └── components
└── views

//tests

├── helpers
│   ├── resolver.js
│   └── start-app.js
├── index.html
├── test-helper.js
└── unit
    ├── comment
    │   ├── model-test.js
    │   └── route-test.js
    └── post
        ├── model-test.js
        └── route-test.js

Do you see the difference? Now we have everything grouped orderly into its own directory (POD). As you application grows you'll be able to easily find the route, model and template for each feature without having to look in a directory with a long list of files.

Yes that is an escape pod from Star Wars!

Setup

Let's create a pod structure. First I'm going to presume that you already have the latest version of Ember CLI installed as of this writing (0.2.0). If not npm remove and npm install the latest one or use the installation guide here.

Where do we want our pods? We can optionally have a single directory that they all live in. To add this configuration simply add the podModulePrefix within your enviornment config. The POD path is always in the following format {appname}/{poddir}

// config/environment.js

  var ENV = {
    modulePrefix: 'pod-example',
    podModulePrefix: 'pod-example/pods
    ...
    },

The podModulePrefix in this example is set to app/pods/. If we don't specify this configuration the default directory will be in the app/ folder.

Generating Pods with Blueprints

Ember CLI has several blueprints that can be used to help us get started with our project. We can use these generators to create files in the pod directory layout by using the --pod option.

$ ember g resource comment --pod
$ ember g resource post --pod

The --pod option will generate the files using the pod structure. So in the above example your directory structure will look like it does below.

├── post
│   ├── model.js
│   ├── route.js
│   └── template.hbs

├── comment
│   ├── model.js
│   ├── route.js
│   └── template.hbs

//tests
└── unit
    ├── comment
    │   ├── model-test.js
    │   └── route-test.js
    └── post
        ├── model-test.js
        └── route-test.js

The above is fairly self-explanatory. The model.js file in each folder is the same as the comment.js and the post.js file you would see in the normal directory structure. Same with route and template. Even the tests lay out is in the pod structure.

If we want we can setup the default structure to always use pods. The easiest way to accomplish this is to create a .ember-cli file in the root of our project directory. It should look like this.

// .ember-cli
{
    "usePods": true
}

Now the --pod is inverted. Therefore you no longer need to use it unless you want to use the normal structure again.

The built-in blueprints that supports the pod structure are shown below.

  • adapter
  • component
  • controller
  • model
  • route
  • resource
  • serializer
  • template
  • transform
  • view

Refactor

What if we needed to refactor our application after one of our features was renamed? Instead of having a post feature we wanted to rename it to posted. That should be easy enough when using pods.

As long as we aren't directly using the name 'post' in of our files, we can just rename/mv the post directory and then update the router.js in the app/ folder.

$ cd app
$ mv post posted
$ vi router.js //change route from post to posted

That's it! Hooray we now have refactored our code without much trouble.

Future

Didn't Ember 2.0 mention something about pods?

The Ember 2.0 RFC referenced something called routeable components. This feature will essentially eliminate controllers. That's another topic for another post. What's important to us right now is that RFC described the feature using a "pod" structure. That's important because the pod structure may become the default in the future so keep that in mind.

Are you guys using pods now? If so feel free to leave a comment below.

Image Credit Wikia Star Wars